1

作成したDLLをロードし、そこから関数を実行するリモートスレッドを作成しようとしています。DLLは正常に動作しています(チェック済み)が、何らかの理由でリモートスレッドが失敗し、DLLが作成されたプロセスが応答を停止します。

ollyDebugを使用して何が問題になっているのかを確認しましたが、2つのことに気づきました...

  1. 私の文字列(dll名と関数名)がリモートスレッドに正しく渡されます
  2. スレッドはLoadLibraryでlasterrorcode87"ERROR_INVALID_PARAMETER"で失敗します

私の最善の推測は、どういうわけか、リモートスレッドがLoadLibraryを見つけることができないということです(これは、リンカーが私のプロセスを尊重して行われているためですか?、推測です...)

私は何が間違っているのですか?

これは、リモート関数のコードです。

static DWORD WINAPI SetRemoteHook (DATA *data)
{
  HINSTANCE dll;
  HHOOK WINAPI hook;
  HOOK_PROC hookAdress;

  dll = LoadLibrary(data->dll);

  hookAdress = (HOOK_PROC) GetProcAddress(dll,data->func);
  if (hookAdress != NULL)
  {
    (hookAdress)(); 
  }
  return 1;
}

編集:

これは、メモリをリモートプロセスに割り当てる部分です。

typedef struct
{
    char* dll;
    char* func;
} DATA;

char* dllName = "C:\\Windows\\System32\\cptnhook.dll";  
char* funcName = "SetHook";
char* targetPrgm = "mspaint.exe";
Data lData;
lData.dll = (char*) VirtualAllocEx( explorer, 0, sizeof(char)*strlen(dllName), MEM_COMMIT, PAGE_READWRITE );
lData.func = (char*) VirtualAllocEx( explorer, 0, sizeof(char)*strlen(funcName), MEM_COMMIT, PAGE_READWRITE );
WriteProcessMemory( explorer, lData.func, funcName, sizeof(char)*strlen(funcName), &v );
WriteProcessMemory( explorer, lData.dll, dllName, sizeof(char)*strlen(dllName), &v );
rDataP = (DATA*) VirtualAllocEx( explorer, 0, sizeof(DATA), MEM_COMMIT, PAGE_READWRITE );
WriteProcessMemory( explorer, rDataP, &lData, sizeof(DATA), NULL );

編集:問題は、リモートスレッドがLoadLibraryベースアドレスではなく「ガベージ」アドレスを呼び出していることのようです。リモートプロセスのLoadLibraryアドレスに間違ってリンクされている可能性のあるVisualStudioはありますか?

編集:ローカルスレッドとまったく同じコードを実行しようとすると(CreateRemoteThreadの現在のプロセスへのハンドルを使用します)、すべてが正常に機能します。これを引き起こす原因は何ですか?

呼び出し元の関数コードを追加する必要がありますか?コードが正しいパラメータを使用してリモートスレッドで実行されているため、その役割を果たしているようです...

コードはVS2010でコンパイルされます。

dataは、名前にchar*が付いた単純な構造体です。(コードで文字列を明示的に記述すると、元のプロセスへのポインタが表示されます)。

私は何が間違っているのですか?

4

2 に答える 2

1

失敗するERROR_INVALID_PARAMETERと、渡されたパラメーターに問題があることを示します。

したがって、どれがdata->dll問題の唯一のパラメータを表しているかを確認する必要があります。

ここで初期化されます:

lData.dll = VirtualAllocEx(explorer, 0, sizeof(char) * (strlen(dllName) + 1), MEM_COMMIT, PAGE_READWRITE);

それでは、参照先のメモリの割り当てがlData.dll本当に成功したかどうかのチェックを追加しましょう。

if (!lData.dll) {
  // do some error logging/handling/whatsoever
}

そうすることで、実装された呼び出しが失敗したことが検出された可能性がありますVirtualAllocEx()

予約されていないページをコミットしようとすると、関数は失敗します。結果のエラー コードは ERROR_INVALID_ADDRESS です。

そのため、問題の呼び出しの 4 番目のパラメーターを推奨どおりに変更することをお勧めします (これも MSDN の言葉どおりです)。

1 つのステップでページを予約してコミットするには、MEM_COMMIT | を指定して VirtualAllocEx を呼び出します。MEM_RESERVE。

PS: allocate の呼び出しについて、この演習を繰り返しlData.funcます。;-)

于 2012-01-02T08:40:45.477 に答える
0

LoadLibrary が、Unicode バージョンである LoadLibraryW (プロジェクトの設定によって異なります) を実際にエイリアシングしている可能性があります。"TCHAR" の代わりに "char" 文字列を使用して Windows API を使用する場合は常に、ANSI バージョン名を明示的に使用する必要があります。これにより、コードを作成するときのデバッグの手間が省けます。また、将来、プロジェクトが Unicode に切り替わった場合に備えて、あなたや他の誰かのためにもなります。

そのため、その恐ろしい未終端文字列の問題を修正することに加えて、必ず次を使用してください。

LoadLibraryA(data->dll);
于 2012-01-06T03:17:24.113 に答える