短縮版:
デバッグ特権でプロセス ハンドルを開いて、デバッグ対象のメモリ内のオブジェクトを指すポインターを定義しようとしています。
ロングバージョン
私は卒業の最終学年であるコンピューター サイエンス大学の学生で、次世代の学生向けの教育目的で使用するアプリケーションを構築する任務を負っています。
なぜ私はここで助けを求めているのですか?ターゲット プラットフォームは Windows で、残念ながら WinAPI についての知識はまったくありません...
さて、ここに基本的な要件があります:
- プログラミング言語: C++
- プラットフォーム: Windows (7 プロフェッショナル)
- 使用IDE:Visual Studio 2012
- 開発を容易にするために不可欠でない場合、追加のライブラリはありません
アプリケーションは何に使用されますか?
このアプリケーションを使用して、生徒はアドレス (この場合は静的アドレス) の処理方法を学習します。デバッグ対象プロセスにはいくつかの静的ポインターがあり、それによって他のポインター自体が多次元ポインターを形成します。生徒たちは、いくつかのデバッグ手法を使用してこれらのベース アドレスを見つけなければならず (これは私の仕事の一部ではありません!)、これらのポインターの末尾にある値を見つけようとします。
私のアプリケーションは、チューターがデバッグ対象プロセスの値や構造をランダムに変更するために使用されます。
一部の検索で最初の答えが得られました。and を使用するReadProcessMemory
とWriteProcessMemory
、デバッグ権限を取得する必要なく、別のプロセスのメモリ内の値を簡単に変更できます。
しかし、私の家庭教師が望んでいるのは、先に書いたベースアドレスを効果的に保持して、デバッグ対象プロセスのメモリ空間を指すポインター (たとえば、unsigned int としましょう) を定義できるようにすることです。彼らは本当にこれを望んでいて、私は彼らにこれを話すことさえできなかったので、私は最後にこれをすることに行き詰まっています...
そして、正確に何が機能する必要がありますか?
次の(疑似)コードが機能する場合、私は自分の仕事を達成したでしょう:
grantThisProcessDebugPrivileges();
openAnotherProcessWhileItsRunning("targetProcess.exe");
unsigned int * targetValue = (unsigned int*) 0xDE123F00;
// or even
myCustomClass * targetClass = (myCustomClass*) 0xDE123F00;
ここで、アドレス 0xDE123F00 は targetProcess.exe のメモリ空間にあります。
これが可能であることはわかっています。そうでなければ、この情報を表示できるデバッガーはありません。
私がこれまでに行ったこと(または試したこと...)
さて、問題は、ターゲットプロセスを開く前にアプリケーションのデバッグ特権をアクティブにする必要があるかどうか、開いた後に実行するか、ターゲットプロセスにこれらの特権を与える必要があるかどうか、本当に混乱しています。
だから私はMSDNで例を見つけて実装しようとしました:
BOOL SetPrivilege(
HANDLE hToken, // token handle
LPCTSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
//
// first pass. get current privilege setting
//
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
&tpPrevious,
&cbPrevious
);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
//
// second pass. set privilege based on previous setting
//
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
if(bEnablePrivilege) {
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
}
else {
tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
}
AdjustTokenPrivileges(
hToken,
FALSE,
&tpPrevious,
cbPrevious,
NULL,
NULL
);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
return TRUE;
};
そして私のメインでは:
HANDLE mainToken;
// I really don't know what this block of code does :<
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &mainToken))
{
if (GetLastError() == ERROR_NO_TOKEN)
{
if (!ImpersonateSelf(SecurityImpersonation))
return 1;
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &mainToken)){
cout << GetLastError();
return 1;
}
}
else
return 1;
}
if (!SetPrivilege(mainToken, SE_DEBUG_NAME, true))
{
CloseHandle(mainToken);
cout << "Couldn't set DEBUG MODE: " << GetLastError() << endl;
return 1;
};
unsigned int processID = getPID("targetProcess.exe");
HANDLE hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if (hproc == NULL)
{
cout << "Couldn't open the process" << endl;
return 1;
};
unsigned int * theValue = (unsigned int*) 0xDE123F;
さて、このコードはエラーなしで実行されます。 SetPrivilege は TRUE を返すので、本当に setSE_DEBUG_NAME
したと思います。これは、設定する必要があるフラグだと思います。
しかし、たとえば、逆参照された の値を出力した後theValue
、アプリケーションがクラッシュし、アクセス違反メッセージが表示されます。これは、私のアプローチが機能しなかったことを示しています。管理者権限で VisualStudio Debugger を起動することに特に注意を払いました (それ以外の場合、SetPrivilege は失敗しました)。
SE_DEBUG_NAME
私はここで本当に無知です.設定が正しいアプローチであるかどうかわからないという事実は、私の全体的な混乱を助長します.
あなたが私を助けてくれることを願っています:)アプリケーションの特定のリクエストに関して私の手は縛られています.完全に異なるアプローチを使用して私の目標を達成するためのアイデアがある場合は、自由に私を啓発してください.それを上司に提示して、私の知識に追加するだけです:D