Introduction
If you want to prevent your program from being cracked by hackers, you can use native code. You can cipher/decipher this code, or it may be self-modifying code for more safety. Now, I'll show how you can execute such native code from your C# programs.
Source code
This example retrieves CPU information.
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;
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);
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;
public UInt32 dwExt;
}