Click here to Skip to main content
Email Password   helpLost your password?

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)
{
  // native function's compiled code


  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);

  // execute native code


  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;
}
You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralPROCESSOR_INFO SIZE!!!!
fuck bill gates
1:49 22 Jan '09  
on WinCe 5.0
PROCESSOR_INFO has 576 bytes length Smile
and a lot of WCHAR fields each 40 chars Smile
Questionhow 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.
AnswerRe: how I do to execute a EXE from inside my application?
Maxim Alekseykin
4:04 14 Jul '08  
Hi Sebastian,

the problem you've encountered is not too simple Smile 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 Smile it'll load any type (either managed or native) exe into the memory and execute it.

Regards.
GeneralWhere did you get the proc binary
I like it
7:18 2 Nov '05  
ConfusedHow we can get the proc binary?

Thanks,

GeneralRe: Where did you get the proc binary
Maxim Alekseikin
10:14 2 Nov '05  
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.
GeneralHow 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); // thow exception
}
}
}

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.
GeneralRe: How to use CStringArray in C# using p/invoke
Maxim Alekseikin, MCAD
2:11 19 Apr '05  
"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.
GeneralRe: How to use CStringArray in C# using p/invoke
shusong
17:16 19 Apr '05  
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
GeneralLegacy 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. Big Grin

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
GeneralInteresting 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.

GeneralRe: Interesting Technique
Maxim Alekseikin
23:09 30 Aug '04  
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 .NetFrown
GeneralGood 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 Wink ...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
GeneralRe: Good Technique (for me!)
Maxim Alekseikin
23:22 30 Aug '04  
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 Smile to execute code from the stack is good. May be I'll be able to integrate both these technics.
GeneralRe: Good Technique (for me!)
Marcello Cantelmo
0:30 31 Aug '04  
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 Wink

regards,
Marcello


Last Updated 30 Aug 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010