リモートプロセスで.dllを起動するための高度なコードインジェクションコードを使用しています。あなたは、これは、ここから例えば/コードsnipetをどのように機能するかを見つけることができます :コードインジェクションを使用したリモートプロセスでの機能の実行
https://sourceforge.net/p/diagnostic/svn/HEAD/tree/src/RemoteInit.cpp
私はいくつかのアプリケーションで、このアプローチは動作しないことに気付きました - それは、ホストアプリケーションがクラッシュします。主な問題は、それが自分のフック関数です提供することで、kernel32.dll GetProcAddress
をインターセプトConEmuHk64.dll
のような特別な種類の3 - サードパーティのソフトウェアのようです - その後私はこのような関数ポインタを取得しています:
*((FARPROC*) &info.pfuncGetProcAddress) = GetProcAddress(hKernel32, "GetProcAddress");
しかし、その代わりに、私はへのポインタを取得していますConEmuHk64.dllにある関数です。
私自身のプロセスでは、この機能を呼び出すことはできますが、リモートプロセスで同じことをしようとすると、ConEmuHk64.dll
が必ずしもそこで利用できるわけではないのでクラッシュします。
私は手動でDOS/NE他のヘッダに歩いて、その関数の正しいアドレスを自動精査する方法のメカニズムを解明しました - ここでのコードスニペットです:
//
// We use GetProcAddress as a base function, with exception to when GetProcAddress itself is hooked by 3-rd party
// software and pointer to function returned to us is incorrect - then we try to locate function manually by
// ourselfes.
//
FARPROC GetProcAddress2(HMODULE hDll, char* funcName)
{
FARPROC p = GetProcAddress(hDll, funcName);
if(!p)
return NULL;
IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER *) hDll;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return p;
IMAGE_NT_HEADERS* pNtHeaders = (IMAGE_NT_HEADERS *) (((char*) pDosHeader) + pDosHeader->e_lfanew);
if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
return p;
IMAGE_OPTIONAL_HEADER* pOptionalHeader = &pNtHeaders->OptionalHeader;
if((char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode)
// Sounds like valid address.
return p;
// Does not sounds right, may be someone hooked given function ? (ConEmuHk64.dll or ConEmuHk.dll)
IMAGE_DATA_DIRECTORY* pDataDirectory = &pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
IMAGE_EXPORT_DIRECTORY* pExp = (IMAGE_EXPORT_DIRECTORY *) ((size_t) pDosHeader + pDataDirectory->VirtualAddress);
ULONG* addrofnames = (ULONG *) ((BYTE*) hDll + pExp->AddressOfNames);
ULONG* funcaddr = (ULONG*) ((BYTE*) hDll + pExp->AddressOfFunctions);
for (DWORD i = 0; i < pExp->NumberOfNames; i++)
{
char* funcname = (char*) ((BYTE*) hDll + addrofnames[i]);
if (strcmp(funcname, funcName) == 0)
{
void* p2 = (void*) ((BYTE*) hDll + funcaddr[i]);
return (FARPROC) p2;
}
} //for
return p;
} //GetProcAddress2
これはGetProcAddress
のために働いているようです - 私は、フックされた機能を検出し、その動作を無効にすることができます。しかし、このアプローチは一般的ではありません。私は他のメソッド、例えばFreeLibrary/AddDllDirectory/RemoveDllDirectory
のための同様の関数呼び出しを試みました - そして、これらの関数ポインタはdll境界のピンポイントを特定します - GetProcAddress
はDOSヘッダの前にアドレスを返します。
if((char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode)
をしかし、数式を向上させることができるかの手掛かりを持っていない:
は、私は、DLL /コードのサイズ範囲での比較が正しいものではないと思われます。
この修正プログラムを完全に作成する方法をお勧めしますか?第三者のソフトウェアが機能を傍受でき、クラッシュせずに生き残ることができますか?