Исполняем 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;
}


Всем удачи.
Максим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.