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;
}
|
|
 |
 | PROCESSOR_INFO SIZE!!!! fuck bill gates | 1:49 22 Jan '09 |
|
 |
on WinCe 5.0 PROCESSOR_INFO has 576 bytes length  and a lot of WCHAR fields each 40 chars 
|
|
|
|
 |
 | how I do to execute a EXE from inside my application? sebastiannielsen | 3:43 12 Jul '08 |
|
 |
I have tried with placing the raw bytes from any EXE, inside the "proc" array, and then using your code to execute it, but I only get "WindowsApplication1 has encountered a problem and needs to quit" message with that send or don't send buttons.
I want to execute a raw EXE stored in a byte array, without writing it to disk and using Shell(). Like putting it in memory and executing it in the same way as the EXE on disk would be double clicked.
|
|
|
|
 |
|
 |
Hi Sebastian,
the problem you've encountered is not too simple in my example the 'proc' array shouldn't contain any calls of any external api including win32 api. You can quite simply modify it to call some of them but any way it can't load and execute an independent exe. My next project and the article might be exactly about this it'll load any type (either managed or native) exe into the memory and execute it.
Regards.
|
|
|
|
 |
 | Where did you get the proc binary I like it | 7:18 2 Nov '05 |
|
 |
How we can get the proc binary?
Thanks,
|
|
|
|
 |
|
 |
for example: - write procedure in C++ or assembly language - compile your programme - see your code under debuger in dissassembly window of your VS - copy byte code of your procedure - a bit edit this code
you can find more information about how to get bynary code from Internet.
|
|
|
|
 |
 | How to use CStringArray in C# using p/invoke shusong | 16:50 18 Apr '05 |
|
 |
In a regular dll using shared MFC dll,there is a variable which type is CStringArray. In c# project , i want to get the string array which length is inconstant.
1, I build a Regular Dll using shared MFC dll named MFCDLL.dll as follows:
extern "C" void PASCAL EXPORT GetValues(CStringArray & stringArray) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString a = "a"; CString b = "b";
stringArray.Add(a); stringArray.Add(b); }
2,build a c# console project named text.exe as follows:
using System; using System.Runtime.InteropServices;
namespace CSharpProject { [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] class CStringArray{ public string[] m_pData; int m_nSize; int m_nMaxSize; int m_nGrowBy; }
class Class1 { [DllImport("MFCDLL.dll", CharSet=CharSet.Auto)] public static extern void GetValues(out CStringArray strarr);
[STAThread] static void Main(string[] args) { CStringArray stringArray = new CStringArray(); GetValues(out stringArray); } } } 3, Copy MFCDLL.dll to the directory of text.exe. 4,double press text.exe ,but program throws exception:System.ExecutionEngineException. When debugging the text.exe,variable:stringArray is undefined value.I think maybe there is some problem with the structure of class CStringArray.
Thank you very much.
|
|
|
|
 |
|
 |
"extern "C" void PASCAL EXPORT GetValues(CStringArray & stringArray)" First, why PASCAL? use __stdcall.
"public string[] m_pData;" Second, why string[]? use char[] or string
[DllImport("MFCDLL.dll", CharSet=CharSet.Auto)] public static extern void GetValues(out CStringArray strarr);
use right CallingConvention value.
if I have time I'll try to resolve your problem. Best regards.
|
|
|
|
 |
|
 |
First,in MFC #define PASCAL __stdcall Second,in MFC, CStringArray is an array of string,so, defining public string[] m_pData;
if you can debug my examples codes, you can find out something wrong.
Thank you for your answer.
Have a good day. Alex China
|
|
|
|
 |
 | Legacy plug-ins Harkos | 10:13 8 Sep '04 |
|
 |
Hi Maxim,
I've been working on a way to use legacy plug-ins (from Win32 DLLs) into .NET and thanks to your article I came up with a great idea to accomplish this using 100% managed code. 
If anyone is also interested, you can visit my article about this solution here.
[]'s Harkos --- "Money isn't our god, integrity will free our soul." Cut Throat - Sepultura
|
|
|
|
 |
 | Interesting Technique Lim Bio Liong | 19:57 30 Aug '04 |
|
 |
I see that you are basically trying to embed x86 executable code into your program and then directly execute it (by making it the startup function of a thread).
This is an interesting way of hiding some functionality from prying eyes (who use tools like ILDASM, etc). I see some usage of this in classes that need custom de-serialization where some fields of a class (e.g. Credit Card Numbers, Passwords, etc) need to be re-constructed via some algorithm (as opposed to direct value-setting).
It would be very interesting to see if we can embed .NET IL into a byte array and then executing the IL in similar ways. I also suggest researching into stuff like CodeDom.
Best Regards, Bio.
|
|
|
|
 |
|
 |
I'm thinking about IL. CodeDom can create file on a disk. But we need an executable code in a memory. now I dont know a way to execute code in memory in .Net
|
|
|
|
 |
 | Good Technique (for me!) Marcello Cantelmo | 11:41 30 Aug '04 |
|
 |
Only who has programmed in assembler x86 can appreciate these potentialities that are not previewed in way directed from the .net compiler
for example: with a ulterior (hide) technique in my crypter I have even implemented a api's hooker to stop a breakpoint on execution of a debugger ...only our creativity!
regards, Marcello
www.cantelmosoftware.com (in continuous modernization)
My last article on CodeProject: http://www.codeproject.com/dotnet/StackCrypt.asp
Nothing is Impossible if Not Tests the Absurdity
|
|
|
|
 |
|
 |
I can create such code in assembler and in VC++. this tools generate good machine code, which we can cut from binary file. Your idea about our own virtual stack machine to execute code from the stack is good. May be I'll be able to integrate both these technics.
|
|
|
|
 |
|
 |
hi Maxim,
in fact, with my "StackCrypt" (with some modification) you can, also, generate to runtime (therefore a inside obfuscator) the code asm to send to the thread...
not enough the decompilation of the code... you must also reconstruct the entire algorithm 
regards, Marcello
|
|
|
|
 |
|
|