シンプルなVMPをお試しください

シェル時点VMP前に書面に従事したいと考えていますが、この事のオンラインブログを説明することだけを見つけるために、何度も繰り返し、比較的小さいます。https://www.cnblogs.com/LittleHann/p/3344261.html

兄の足跡をたどって、彼はいくつかの試み、マークそれを作りました。

ギャングスター私は、自分自身を記述するための関数で実行をシミュレートstrcmpのを書いて、呼び出し規約WINAPI、呼び出された関数のスタック自身のバランスを設定し、それとは異なります。

呼び出し後のように、元のテキストECXを変更しない、問題を見つけましたが、私ではありません。スタートは、スタックフレームを開いた後、機能のECXの戻り値は、ECXを保存呼び出すために使用されています。

書式#include <iostreamの> 
の#include "WINDOWS.H" 

/ *ここでダミー命令、2 * /シミュレートされた命令
// 0x12345678のプッシュプッシュの4バイト
に#define vPushData 0x10を
呼び出す// 4バイト0x12345678のコールアドレス
の#define vcall 0x12を
//ターミネーター
、販売0xFFでは、の#define 

/ * 
	この仮想命令の構成である
	STRオフセットプッシュ
	STRオフセット押すと、文字列スタックのアドレス
	コールのstrcmp; 
* / 
BYTE bVmData [] = {vPushData、 0x00で、0x00に、0x00で、0x00に、
		   vPushData、0x00で、0x00に、0x00で、0x00に、
		   vcall、0x00で、0x00に、0x00で、0x00に、
		   自動販売機販売}; 

//単純な仮想化エンジン
_declspec(裸の)無効VM(PVOID pvmData)
{ 
	__asm 
	{ 
		//この関数はスタックフレームを開きます
		EBPプッシュ
		MOVのEBP、ESP 
		サブESP、0x64は
	    // ECXでvCodeアドレス取る
	    MOV ECX、DWORD PTR SS:[EBPの+ 8] 
	__vstart:
	    //らの第1バイトを取る
		、MOVのBLバイトのPTR DS: [ECX] 
		//比較はvPushDataない
		vPushData、CMP BL 
		です// __vPushDataブロックがジャンプ
		JE __vPushData 
		//比較がvcallされていない
		CMP BLを、vcall 
		//が__vcallとにジャンプしている
		__vcallとJE 
		//比較ではありませんVEND 
		CMP BL、VENDは
		// __vEndにジャンプしている
		JE __vEndの
		int型3。
	__vPushData:
		// ECX + 1、4バイトの背中を指し、vPushDataをスキップ
	    ECXである株式会社
		データの// 4つのバイトがEDXに入れ(すなわち、アドレス)
		MOV EDX、DWORD PTR DS:[ECX] 
		//プッシュアドレス
		EDXは、プッシュ 
		// ECX + 4、次のデータポイント。
		追加ECX ,. 4 
		ブロック__vstartへ//ジャンプを
		JMPの__vstart 
	__vcallと:
		// ECXの+ 1、オフセットアドレス
	    incはECXです
		//関数アドレス削除
		[ECX]:MOV EDX、DWORD PTR DS 
		//はECXを保存します値
		MOV DWORD PTR DS:[EBP-20がある]、ECX 
		//コール機能アドレスは
		EDXを呼び出し
		ECXのの//戻り値
		のMOV ECX、DWORD PTR DS: - [EBP 20である] 
		。// + ECX 1、4つのアドレスは、オフセット
		ECXは,. 4追加
		__vstartする//ジャンプを
		JMP __vstart 
	__vEnd:
		均衡//スタックを
		ESPを追加し、0x64 
		POPのEBPの
		RETは
	} 
}は

、文字列比較関数独自の実装// 
int型をWINAPI MyStrCmp(のchar *のSRC、 char型* DST) 
{ 
	INT NNUM = 0。
	一方、(!(NNUM = *(のchar *)SRC - *(のchar *)DST)&& * DST) 
    //取得関数の戻り値
		SRC ++、++ DST; 
	IF(NNUM <0)
	{ 
		NNUM = -1; 
	} 
	そうIF(NNUM> 0)
	{ 
		NNUM = 1; 
	} 
	; NNUMを返す

} 

int型のmain()
{ 
	購入チャーstr1が[] =」利用可能! "; 
	のchar str2には、[] ="「購入可能!; 

	_asm PUSHAD 

	//は、関数ポインタを取得
	int型(* WINAPI pMyStrCmp)(SRCチャー*、CHAR * DST); 
	pMyStrCmp = MyStrCmp; 
	//仮想命令データ変更
	*を(DWORD *)(bVmData + 1)=(DWORD)STR1; 
	*(DWORD *)(bVmData + 5 + 1)=(DWORD)STR2;。。
	。*(DWORD *)(bVmData + 10 + 1)=(DWORD)pMyStrCmp; 

	/ /ダミー命令実行
	VM(bVmData)を、 
	{ 
	  MOV nRet、EAX
        
	INT nRet = 0; 
	_asmの  
	  popad 
	} 
	のprintf( "%dの"、nRet)。

	0を返します。
}


おすすめ

転載: blog.51cto.com/14317856/2409555