Исполняем native код из под .Net
От: Максим Алексейкин США  
Дата: 17.08.04 09:51
Оценка: 99 (12)
Привет всем.
Вот решил подеиться, может кому пригодиться.

Предистория
есть в SDK пример получения данных CPU. Найти его можно в MSDN по ключевому сову cpuid.
и понадобилось мне выполнить этод код из приложения на C# (заказчик не желал ничего слышать о C++)... далее было изучение того, как писать самомодифицирующийся код под виндой. отдельное спасибо Крису Касперски (хотя он в этом не сильно нуждается ).

Собственно функция:
из кода, думаю, все понятно.

private void button1_Click(object sender, System.EventArgs e)
{
  byte[] proc = new byte[] {
    0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x00, 0x53, 0x51, 
    0x52, 0x57, 0x8B, 0x7D, 0x08, 0x33, 0xC0, 0x0F, 
    0xA2, 0x89, 0x07, 0x89, 0x5F, 0x04, 0x89, 0x57, 
    0x08, 0x89, 0x4F, 0x0C, 0xB8, 0x01, 0x00, 0x00, 
    0x00, 0x0F, 0xA2, 0x89, 0x47, 0x10, 0x89, 0x57, 
    0x14, 0xB8, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xA2, 
    0x3D, 0x00, 0x00, 0x00, 0x80, 0x72, 0x0A, 0xB8, 
    0x01, 0x00, 0x00, 0x80, 0x0F, 0xA2, 0x89, 0x57, 
    0x18, 0x5F, 0x59, 0x5B, 0x5A, 0x8B, 0xE5, 0x5D, 
    0x33, 0xC0, 0xC2, 0x04, 0x00
                           };
  UInt32 funcAddr = VirtualAlloc(0, (UInt32)proc.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  Marshal.Copy(proc, 0, (IntPtr)(funcAddr), proc.Length);

  IntPtr hThread = IntPtr.Zero;
  UInt32 threadId = 0;

  // prepare data
  PROCESSOR_INFO info = new PROCESSOR_INFO();
  IntPtr pinfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PROCESSOR_INFO)));
  Marshal.StructureToPtr(info, pinfo, false);

  hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
  WaitForSingleObject(hThread, 0xFFFFFFFF);

  // retrive data
  info = (PROCESSOR_INFO)Marshal.PtrToStructure(pinfo, typeof(PROCESSOR_INFO));
  Marshal.FreeHGlobal(pinfo);

  CloseHandle(hThread);
  VirtualFree((IntPtr)funcAddr, 0, MEM_RELEASE);
}

private UInt32 MEM_COMMIT = 0x1000;
private UInt32 PAGE_EXECUTE_READWRITE = 0x40;
private UInt32 MEM_RELEASE = 0x8000;

[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")]
private static extern bool VirtualFree(IntPtr lpAddress, UInt32 dwSize, UInt32 dwFreeType);
        [DllImport("kernel32")]
private static extern IntPtr CreateThread(
  UInt32 lpThreadAttributes,
  UInt32 dwStackSize,
  UInt32 lpStartAddress,
  IntPtr param,
  UInt32 dwCreationFlags,
  ref UInt32 lpThreadId
);
[DllImport("kernel32")]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(
  IntPtr hHandle,
  UInt32 dwMilliseconds
);
[DllImport("kernel32")]
private static extern IntPtr GetModuleHandle(
  string moduleName
);
[DllImport("kernel32")]
private static extern UInt32 GetProcAddress(
  IntPtr hModule,
  string procName
);
[DllImport("kernel32")]
private static extern UInt32 LoadLibrary(
  string lpFileName
);
[DllImport("kernel32")]
private static extern UInt32 GetLastError();

[StructLayout(LayoutKind.Sequential)]
internal struct PROCESSOR_INFO 
{
  public UInt32 dwMax;
  public UInt32 id0;
  public UInt32 id1;
  public UInt32 id2;
  
  public UInt32 dwStandard;
  public UInt32 dwFeature;

  // if AMD
  public UInt32 dwExt;
}


Всем удачи.
Максим.
Re: Исполняем native код из под .Net
От: DEMON HOOD  
Дата: 20.08.04 20:20
Оценка:
Здравствуйте, Максим Алексейкин, Вы писали:

МА>[c#]

МА>private void button1_Click(object sender, System.EventArgs e)
МА>{
МА> byte[] proc = new byte[] {
МА> 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x00, 0x53, 0x51,
МА> 0x52, 0x57, 0x8B, 0x7D, 0x08, 0x33, 0xC0, 0x0F,
МА> 0xA2, 0x89, 0x07, 0x89, 0x5F, 0x04, 0x89, 0x57,
МА> 0x08, 0x89, 0x4F, 0x0C, 0xB8, 0x01, 0x00, 0x00,
МА> 0x00, 0x0F, 0xA2, 0x89, 0x47, 0x10, 0x89, 0x57,
МА> 0x14, 0xB8, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xA2,
МА> 0x3D, 0x00, 0x00, 0x00, 0x80, 0x72, 0x0A, 0xB8,
МА> 0x01, 0x00, 0x00, 0x80, 0x0F, 0xA2, 0x89, 0x57,
МА> 0x18, 0x5F, 0x59, 0x5B, 0x5A, 0x8B, 0xE5, 0x5D,
МА> 0x33, 0xC0, 0xC2, 0x04, 0x00

подскажи, что здесь...
... <<silent Rsdn@Home 1.1.4 beta 1 Windows XP 5.1.2600.0 >>
Re[2]: Исполняем native код из под .Net
От: DEMON HOOD  
Дата: 21.08.04 20:15
Оценка:
Здравствуйте, DEMON HOOD, Вы писали:

DH>Здравствуйте, Максим Алексейкин, Вы писали:


МА>>[c#]

МА>>private void button1_Click(object sender, System.EventArgs e)
МА>>{
МА>> byte[] proc = new byte[] {
МА>> 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x00, 0x53, 0x51,
МА>> 0x52, 0x57, 0x8B, 0x7D, 0x08, 0x33, 0xC0, 0x0F,
МА>> 0xA2, 0x89, 0x07, 0x89, 0x5F, 0x04, 0x89, 0x57,
МА>> 0x08, 0x89, 0x4F, 0x0C, 0xB8, 0x01, 0x00, 0x00,
МА>> 0x00, 0x0F, 0xA2, 0x89, 0x47, 0x10, 0x89, 0x57,
МА>> 0x14, 0xB8, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xA2,
МА>> 0x3D, 0x00, 0x00, 0x00, 0x80, 0x72, 0x0A, 0xB8,
МА>> 0x01, 0x00, 0x00, 0x80, 0x0F, 0xA2, 0x89, 0x57,
МА>> 0x18, 0x5F, 0x59, 0x5B, 0x5A, 0x8B, 0xE5, 0x5D,
МА>> 0x33, 0xC0, 0xC2, 0x04, 0x00

DH>подскажи, что здесь...


        push    ebp
        mov    ebp, esp
        sub    esp, 0
        push    ebx
        push    ecx
        push    edx
        push    edi
        mov    edi, [ebp+8]
        xor    eax, eax
        cpuid    
        mov    [edi], eax
        mov    [edi+4], ebx
        mov    [edi+8], edx
        mov    [edi+0Ch], ecx
        mov    eax, 1
        cpuid    
        mov    [edi+10h], eax
        mov    [edi+14h], edx
        mov    eax, 80000000h
        cpuid    
        cmp    eax, 80000000h
        jb    short loc_0_41
        mov    eax, 80000001h
        cpuid    
        mov    [edi+18h], edx

loc_0_41:                ; 
        pop    edi
        pop    ecx
        pop    ebx
        pop    edx
        mov    esp, ebp
        pop    ebp
        xor    eax, eax



у меня правильно получилось?
... <<silent Rsdn@Home 1.1.4 beta 1 Windows XP 5.1.2600.0 >>
Re[2]: Исполняем native код из под .Net
От: adontz Грузия http://adontz.wordpress.com/
Дата: 22.08.04 11:47
Оценка: 3 (1)
Здравствуйте, DEMON HOOD, Вы писали:

DH>подскажи, что здесь...



00407030 55               push        ebp  
00407031 8B EC            mov         ebp,esp 
00407033 83 EC 00         sub         esp,0 
00407036 53               push        ebx  
00407037 51               push        ecx  
00407038 52               push        edx  
00407039 57               push        edi  
0040703A 8B 7D 08         mov         edi,dword ptr [ebp+8] 
0040703D 33 C0            xor         eax,eax 
0040703F 0F A2            cpuid            
00407041 89 07            mov         dword ptr [edi],eax 
00407043 89 5F 04         mov         dword ptr [edi+4],ebx 
00407046 89 57 08         mov         dword ptr [edi+8],edx 
00407049 89 4F 0C         mov         dword ptr [edi+0Ch],ecx 
0040704C B8 01 00 00 00   mov         eax,1 
00407051 0F A2            cpuid            
00407053 89 47 10         mov         dword ptr [edi+10h],eax 
00407056 89 57 14         mov         dword ptr [edi+14h],edx 
00407059 B8 00 00 00 80   mov         eax,80000000h 
0040705E 0F A2            cpuid            
00407060 3D 00 00 00 80   cmp         eax,80000000h 
00407065 72 0A            jb          code+41h (407071h) 
00407067 B8 01 00 00 80   mov         eax,80000001h 
0040706C 0F A2            cpuid            
0040706E 89 57 18         mov         dword ptr [edi+18h],edx 
00407071 5F               pop         edi  
00407072 59               pop         ecx  
00407073 5B               pop         ebx  
00407074 5A               pop         edx  
00407075 8B E5            mov         esp,ebp 
00407077 5D               pop         ebp  
00407078 33 C0            xor         eax,eax 
0040707A C2 04 00         ret         4


Выясняется так


unsigned char code[] = {0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x00, 0x53, 0x51, 
0x52, 0x57, 0x8B, 0x7D, 0x08, 0x33, 0xC0, 0x0F, 
0xA2, 0x89, 0x07, 0x89, 0x5F, 0x04, 0x89, 0x57, 
0x08, 0x89, 0x4F, 0x0C, 0xB8, 0x01, 0x00, 0x00, 
0x00, 0x0F, 0xA2, 0x89, 0x47, 0x10, 0x89, 0x57, 
0x14, 0xB8, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xA2, 
0x3D, 0x00, 0x00, 0x00, 0x80, 0x72, 0x0A, 0xB8, 
0x01, 0x00, 0x00, 0x80, 0x0F, 0xA2, 0x89, 0x57, 
0x18, 0x5F, 0x59, 0x5B, 0x5A, 0x8B, 0xE5, 0x5D, 
0x33, 0xC0, 0xC2, 0x04, 0x00};
//
int main( int argc, char * argv[], char * envp[] )
    {
        LPVOID lpCode = &code[0];
        __asm call DWORD PTR [lpCode];
        return 0;
    }
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Исполняем native код из под .Net
От: Максим Алексейкин США  
Дата: 23.08.04 08:49
Оценка:
Да очень, похоже (исходники дома). только все выглядело примерно так:

__declspec(naked)
DWORD func (LPVOID param)
{
  /* prolog */
  __asm {
      push   ebp
      mov      ebp, esp
      sub      esp, __LOCAL_SIZE
  }

  __asm
  {
    ...  тот самый асм
  }

  /* epilog */
  __asm  
  {
      mov      esp, ebp
      pop      ebp
      ret      4
  }   
}
Re[3]: Исполняем native код из под .Net
От: Максим Алексейкин США  
Дата: 23.08.04 08:55
Оценка: -2
еще, для отладки можно в любое место массива proc вставлять код 0xCC (int 3)
Re: Исполняем native код из под .Net
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.09.04 20:53
Оценка: 1 (1) :))
Здравствуйте, Максим Алексейкин, Вы писали:

Ну, вот... а говорили что с приходом С программирование в машинных кодах отомрет. А вот пришел шарп и на тебе.

Все же на С это было бы нманого проще.
... << RSDN@Home 1.1.4 beta 2 >>
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Исполняем native код из под .Net
От: Максим Алексейкин США  
Дата: 23.09.04 09:02
Оценка:
Здравствуйте, Максим Алексейкин, Вы писали:

МА>еще, для отладки можно в любое место массива proc вставлять код 0xCC (int 3)


господа, прокоментируйте минусы.
Re[5]: Исполняем native код из под .Net
От: retalik www.airbandits.com/
Дата: 23.09.04 09:05
Оценка: +1
Здравствуйте, Максим Алексейкин, Вы писали:

МА>>еще, для отладки можно в любое место массива proc вставлять код 0xCC (int 3)

МА>господа, прокоментируйте минусы.

Видимо, несогласны насчет "любого места". 0xCC в середине чужой 3-байтовой инструкции будет большим сюрпризом.
Успехов,
Виталий.
Re: Исполняем native код из под .Net
От: Максим Алексейкин США  
Дата: 28.03.06 15:11
Оценка:
в продолжении темы случайно наткнулся на статью от MS
Executing Assembly Code with the CallWindowProc API in Visual Basic .NET
А что обычный С/С++ отменили?
От: Sheridan Россия  
Дата: 11.04.06 03:09
Оценка:
Нельзя этот код на нормальном языке написать и в dll воткнуть?

[RSDN@Home][1.2.0][alpha][648]
[Людей мучают не вещи, а представления о них. [Эпиктет]]
Matrix has you...
Re: А что обычный С/С++ отменили?
От: Oyster Украина https://github.com/devoyster
Дата: 11.04.06 06:46
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Нельзя этот код на нормальном языке написать и в dll воткнуть?


Цитата из сообщения:

... (заказчик не желал ничего слышать о C++) ...

http://rsdn.org/File/27948/bf.gif
Re[2]: А что обычный С/С++ отменили?
От: Sheridan Россия  
Дата: 11.04.06 07:14
Оценка:
Здравствуйте, Oyster, Вы писали:

O>Здравствуйте, Sheridan, Вы писали:


S>>Нельзя этот код на нормальном языке написать и в dll воткнуть?


O>Цитата из сообщения:


O>

O>... (заказчик не желал ничего слышать о C++) ...


Заказчик заказывал код или нормальную работу софта?
имхо с вашей стороны наблюдается неуверенность менеджеров в себе и в недостатке понимания менеджерами состояния дел. О как сказал

[RSDN@Home][1.2.0][alpha][648]
[Hет ничего глупее желания всегда быть умнее всех. [Ф. Ларошфуко]]
Matrix has you...
Re[3]: А что обычный С/С++ отменили?
От: Oyster Украина https://github.com/devoyster
Дата: 11.04.06 07:59
Оценка:
Здравствуйте, Sheridan, Вы писали:

O>>Цитата из сообщения:


O>>... (заказчик не желал ничего слышать о C++) ...


S>Заказчик заказывал код или нормальную работу софта?


Разве ты никогда не общался с этими забавными зверьками?

S>имхо с вашей стороны наблюдается неуверенность менеджеров в себе и в недостатке понимания менеджерами состояния дел. О как сказал


А причём тут я, вообще? Я к этой проблеме не имею ни малейшего отношения У нас бы таким извратом не занимались. Но изврат всё равно интересный
http://rsdn.org/File/27948/bf.gif
Re[4]: А что обычный С/С++ отменили?
От: Sheridan Россия  
Дата: 11.04.06 08:39
Оценка: :)
Здравствуйте, Oyster, Вы писали:

S>>Заказчик заказывал код или нормальную работу софта?

O>Разве ты никогда не общался с этими забавными зверьками?
Не имел возможности. Большей частью програмлю для себя либо не стеснен в выборе.

O>А причём тут я, вообще? Я к этой проблеме не имею ни малейшего отношения У нас бы таким извратом не занимались. Но изврат всё равно интересный

Сорри, как всегда на ник не посмотрел...

[RSDN@Home][1.2.0][alpha][648]
[Hе может долго нравиться тот, кто умен всегда на один лад. [Ф. Ларошфуко]]
Matrix has you...
Re[5]: А что обычный С/С++ отменили?
От: Oyster Украина https://github.com/devoyster
Дата: 11.04.06 08:44
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>>>Заказчик заказывал код или нормальную работу софта?

O>>Разве ты никогда не общался с этими забавными зверьками?
S>Не имел возможности. Большей частью програмлю для себя либо не стеснен в выборе.

Ну тогда тебе, наверное, тяжело судить о том, как порой приходится общаться с заказчиком.
http://rsdn.org/File/27948/bf.gif
Re[6]: А что обычный С/С++ отменили?
От: Sheridan Россия  
Дата: 11.04.06 09:01
Оценка:
Здравствуйте, Oyster, Вы писали:

O>Ну тогда тебе, наверное, тяжело судить о том, как порой приходится общаться с заказчиком.

Не спорю, тяжело. Но по своему опыту общения уверен что если подходить к делу без виляний хвостом а аргументированно отстаивать свою точку зрения то многооое получится....

[RSDN@Home][1.2.0][alpha][648]
[Hичего слишком! [Солон]]
Matrix has you...
Re[7]: А что обычный С/С++ отменили?
От: Oyster Украина https://github.com/devoyster
Дата: 11.04.06 09:35
Оценка:
Здравствуйте, Sheridan, Вы писали:

O>>Ну тогда тебе, наверное, тяжело судить о том, как порой приходится общаться с заказчиком.

S>Не спорю, тяжело. Но по своему опыту общения уверен что если подходить к делу без виляний хвостом а аргументированно отстаивать свою точку зрения то многооое получится....

В целом я согласен, безусловно, но как вариант может получиться потерять заказчика У тебя ведь не было опыта общения с конечным заказчиком, насколько я понял.

PS: Ветка неуклонно скатывалась в оффтоп...
http://rsdn.org/File/27948/bf.gif
Re[8]: А что обычный С/С++ отменили?
От: Sheridan Россия  
Дата: 11.04.06 09:44
Оценка:
Здравствуйте, Oyster, Вы писали:

O>В целом я согласен, безусловно, но как вариант может получиться потерять заказчика У тебя ведь не было опыта общения с конечным заказчиком, насколько я понял.

Яж вроде говорил что опыта не имею и говорю имхо. Лично я попытался бы выяснить для каких целей заказчику понадобилось такое. Может он в мультике про роботов чтото наподобии слышал... Ведь вполне возможна ситуация когда делаеш все точно так как говорит заказчик а потом оказывается что все не так. В плане заработать это конечно гут. Контракт выполнили мол от строчки до строчки, все как написано, а отношение уже другое... Лично я бы задумался надо доверием к исполнителю, если тот не интересуется чемто в ходе работы, не спрашивает о необходимости внесений изменений и прочего.

Еще раз: все мое имхо. Я бы делал именно так.

O>PS: Ветка неуклонно скатывалась в оффтоп...

Такая уж тенденция на форумах...

[RSDN@Home][1.2.0][alpha][648]
[Жестокость законов препятствует их соблюдению. [Ш. Монтескье]]
Matrix has you...
Re[9]: А что обычный С/С++ отменили?
От: Oyster Украина https://github.com/devoyster
Дата: 11.04.06 10:57
Оценка: +1
Здравствуйте, Sheridan, Вы писали:

S>Еще раз: все мое имхо. Я бы делал именно так.


В теории всё именно так, как ты написал. На практике, увы, далеко не всегда.

Я практически уверен, что с заказчиком пытались договориться насчёт использования Си + P/Invoke, иначе не было бы той цитаты в исходном сообщении, которую я приводил. Видимо, не удалось; кстати, это может означать не то, что договаривались плохо, но то, что заказчик попался невменяемый, потому что изврат с хранением машинного кода в массиве это, пожалуй, худший из вариантов. Но заказчиками перебирать не всегда приходится, особенно в мелких начинающих аутсорсинговых конторах.

O>>PS: Ветка неуклонно скатывалась в оффтоп...

S>Такая уж тенденция на форумах...

Всё-таки давай прекратим оффтоп — вроде больше обсуждать нечего
http://rsdn.org/File/27948/bf.gif
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.