CreateRemoteThreadによるリモート・コード注入技術による64ビット・マシンでの問題


まず、関連関数のプロトタイプを見てみましょう.
    1.モジュールのロードとアンインストール
HMODULE WINAPI LoadLibraryA(const char* name);
HMODULE WINAPI LoadLibraryW(const wchar_t* name);
BOOL WINAPI FreeLibrary(HMODULE module);
逆風プログラミングの逸品
    2.スレッド関数プレースホルダ
DWORD WINAPI ThreadFunc(LPVOID param);//windows.h
unsigned __stdcall thread_proc(void* param);//process.h
    3.スレッド戻り値の取得
BOOL WINAPI GetExitCodeThread(HANDLE thread,LPDWORD result);
一、CreateRemoteThreadを利用してリモートプロセスにモジュールをロードするのは問題ないはずです.
LoadLibraryA(
const char*
 );
LoardLibraryW(
const wchar_t
* );
ThreadFunc(
LPVOID
 );
thread_proc(
void
* );
1番目のパラメータはすべてポインタで、ビット長は同じです.
だからまだ
であるかのように
モジュールロード関数
を選択します.
スレッド関数
であるかのように
ロードされたモジュールのファイル名
を選択します.
スレッドパラメータ
リモートスレッドの開始
CreateRemoteThread( ... , LoadLibraryA , "injectant.dll", ...);
注意:最初はdllとアプリケーションをディレクトリの下に置きました. 相対的な経路を使って、その他は絶対的な経路を使うべきで、さもなくばその他のプログラムは注入できません
もちろん、これは偽コードです.
この方法が機能するには,リモートプロセスにおけるLoadLibraryAのアドレスを取得し,リモートプロセスのアドレス空間に「injectant.dll」と書き込む必要がある.
二、CreateRemoteThreadを利用してリモートプロセスでモジュールをアンインストールしても問題ないはずです.FreeLibrary(HMODULE) ); ThreadFunc(LPVOID ); thread_proc(void* ); ポインタは64ビットのアドレス空間を指すために64ビット長が必要である.HMODULEはモジュールのベースアドレスを表すために用いられ、アドレス空間は64ビットであり、HMODULEも64ビットが必要である.したがって、モジュールアンインストール関数をスレッド関数としてロードされたモジュールハンドルをスレッドパラメータとしてリモートスレッドCreateRemoteThread(…,FreeLibrary,hModule,…)を起動することができる.
三、問題は:リモートプロセスにロードされたモジュールハンドルをどのように取得するか.
    三.1、スレッド戻り値スレッド関数の原型は戻り値タイプから二つに分けられる.DWORDとunsignedは、マシンワード長、すなわちunsignedを返すのが合理的であると言える.また、DWORDを返すコードに依存しても、戻りタイプがunsignedに変更されたからといって問題はならない.前者は需要が少なく、後者はより多く与えられる.前者は一度切断する必要があり、32ビットのDWORD戻り値を取得します.スレッド関数はDWORDのため、16ビットマシンでは、マシンワード長を戻り値として使用すると、値の範囲が少なすぎるため、スレッド関数の戻り値は、 uint_least 32_t 16ビットマシンで、2つのマシンワード長を使用して戻り値をつづる  32ビット32ビットマシンで、マシンワード長を使用して戻り値            32ビット64ビットマシンで、マシンワード長を使用して戻り値            64ビットつまり、スレッド関数は64ビットのモジュールハンドルを返す可能性があります.なぜですか.  戻る前に自分で断ち切る必要はないのか.    三.2、取得スレッド戻り値BOOL GetExitCodeThread(HANDLE thread,LPDWORDresult);
2番目のパラメータをマシンワード長データへのポインタに変更できますか?  できないかもしれません.関数はもっと必要です.resultはマシンワード長データを指すポインタでなければなりません.つまり、resultが指す連続8バイトは書き込み可能です.しかし、呼び出し元はもっと少ないです.呼び出し元はマシンワード長を提供せず、連続4バイトを指すポインタだけを提供する可能性があります.次のコードがどんなに一般的か考えてみてください.(特にwindowsで定義されたデータ型が好きな同級生)DWORD code=0;GetExitCodeThread(thread,&code);GetExitCodeThreadは絶対に8バイトの内容を書き込んではいけません.そのため、前のステップでロードしたモジュールのハンドルを取得できない可能性が高いので、アンインストールできない可能性があります.四、64ビットマシンにまとめると、この技術を使ってモジュールをリモートロードすることができます.しかし、アンインストールできるかどうかは、1.64ビットのスレッド戻り値タイプ2.スレッド戻り値を取得する関数がどのバイトの戻り値を取得するのに十分ですか.両方が64ビットであれば、この技術は依然として可能です.
Win 7 CreateRemoteThread別の使用方法
win 7には気づかなかった 注入できない問題は、上の階のように、64は64ビットのdll、exeも64ビット、64ビットの下で注入を操作しなければならない.DLLは64ビット、注入動作のEXEも64ビットでなければならない.皆さんの解答に感謝します.正解はVS 2010でDLLを64ビットに翻訳すればいいということです
VS 2010は64ビット設定値にコンパイル:Project->properties->Configuration Properties->Linker->Advanced->Target Machine
Libライブラリも64ビットです. Project ->properties->Configuration Properties -> VC++ Directories
Properties->Configuration Properties、右上のConfiguration Managerをクリックして、リストの対応するプロジェクトのplatformがx 64に設定されているかどうかを確認します.私の問題は、x 64に設定すると解決します. 
システムが64ビット関数かどうかを判断する
/************************************************************************/
/* 
	return TRUE 64             32    , 64    
*/
/************************************************************************/
BOOL CDllInjectionDlg::IsWow64()
{
	typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
	LPFN_ISWOW64PROCESS fnIsWow64Process;

	BOOL bIsWow64 = FALSE;
	fnIsWow64Process =(LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
	if (NULL != fnIsWow64Process)
	{
		if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
		{
			MessageBox(TEXT("IsWow64 error!"));
		}

	}
	return bIsWow64;
}

関連リンクを入力: http://blog.csdn.net/ithzhang/article/details/7051558