/*
修改记录
    2008-5-11 8:07 曲滨
        >> 基本实现预期功能
        [!] 明天进行优化

    2008-5-12 15:54 曲滨
        [E] 优化完成
        [N] 加入 NativeCodeHelper 类便于使用 

    2010-6-17 周振兴
 
        修改兼容性,可在开启DEP及Vista/Win7中运行。

*/


namespace
NShellNativeCode
{
    

using
System;
    

using
System.Runtime.InteropServices;

    
delegate

int
AddProc(
int
p1,
int
p2);
    

class
Program
    {
        

static

void
Main(
string
[] args)
        {
            

byte
[] codeBytes
=
{
                  

0x8B
,
0x44
,
0x24
,
0x08
    
//
mov eax,[esp+08h]


                ,
0x8B
,
0x4C
,
0x24
,
0x04
    
//
mov ecx,[esp+04h]


                ,
0x03
,
0xC1
                
//
add    eax,ecx


                ,
0xC3
                        
//
ret


                };

            
/*

            上面的字节数组,就是下面函数的本机代码;
            int add(int x,int y) {
                return x+y;
            }
            
            

*/

            IntPtr handle
=
IntPtr.Zero;
            handle

=
VirtualAlloc(
                IntPtr.Zero,
                codeBytes.Length,
                MEM_COMMIT

|
MEM_RESERVE,
                PAGE_EXECUTE_READWRITE);

            
try

            {

                Marshal.Copy(codeBytes,
0
, handle, codeBytes.Length);

                AddProc add
                  
=
Marshal.GetDelegateForFunctionPointer(handle,
typeof
(AddProc))
as
AddProc;

                
int
r
=
add(
1976
,
1
);

                Console.WriteLine(

本机代码返回:{0}

, r);

            }
            
finally

            { 
                VirtualFree(handle,

0
, MEM_RELEASE);
            }

            Console.ReadLine();
        }

        
//
Windows API


        [DllImport(

Kernel32.dll

, EntryPoint
=


VirtualAlloc

)]
        

public

static

extern
IntPtr VirtualAlloc(IntPtr address,
int
size,
uint
allocType,
uint
protect);

        [DllImport(

Kernel32.dll

, EntryPoint
=


VirtualFree

)]
        

public

static

extern

bool
VirtualFree(IntPtr address,
int
size,
uint
freeType);

        
//
flags


        
const

uint
MEM_COMMIT
=

0x1000
;
        

const

uint
MEM_RESERVE
=

0x2000
;

        
const

uint
PAGE_EXECUTE_READWRITE
=

0x40
;

        
const

uint
MEM_RELEASE
=

0x8000
;
    }
}