バックグラウンド
特定のソフトウェアのマルチオープン防止制限を解除する必要があるため、そうする必要があります。
ただし、ウィンドウクラス名の変更は、ウィンドウタイトル(直接SetWindowText)を変更するほど簡単ではなく、使用する直接APIはありません。数日間の調査の後、ウィンドウクラス名を変更する2つの方法を要約しました。
- peファイルを変更します(シェル化のないプログラムに適しています)
- フックRegisterClass(パックされたプログラムに適しています)
peファイルを変更する
例としてdbgview.exeを取り上げると、シェルレスであることがわかります。
プログラムを開いた後、メインウィンドウクラスの名前はdbgviewClassになります。
16進数をダイで直接表示し、dbgviewClassを検索します。
直接変更して保存し、プロセスを再度開いてクラス名を表示します。
変更されました!
フックRegisterClass
ご存知のように、シェルの役割は次の機能にすぎません。
- 圧縮
- アンチダイナミックデバッグ
- 静解析
したがって、ソフトウェアがシェル化されている場合、最初のメソッドを使用してクラス名の文字列を見つけることはできません(実際のコードはプログラムの実行時にのみ復号化され、16進ツールで表示されるのは暗号文であるため)
まず、ウィンドウを作成するためのコードを見てみましょう。
//1、设计窗口
WNDCLASS wc;
wc.cbClsExtra = 0; //类额外的内存,通常为零
wc.cbWndExtra = 0; //窗口额外的内存,通常为零
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景
wc.hCursor = LoadCursor(NULL, IDC_HAND); //设置光标,如果第一个参数为NULL,代表使用系统提供的默认光标
wc.hIcon = LoadIcon(NULL, IDI_WARNING);
wc.hInstance = hInstance; //当前实例句柄,WinMain函数中形参即可
wc.lpfnWndProc = WindowProc; //窗口过程函数,回调函数,名称可以随便起
wc.lpszClassName = TEXT("WINDOW"); //指定窗口类名
wc.lpszMenuName = NULL; //菜单名,没有填NULL
wc.style = 0; //0代表默认风格
//2、注册窗口类
RegisterClass(&wc);
//3、创建窗口
HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("TEXT WINDOW"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT ,
NULL, NULL, hInstance, NULL);
//4、显示和更新
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
//5、通过循环取消息
MSG msg;
while(1)
{
if (GetMessage(&msg, NULL,0,0) == FALSE)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
フックCreateWindowExまたはCreateWindowを使用してlpClassNameパラメーターを変更しようとしましたが、これにより、関数は1047エラーを返します(ウィンドウカテゴリが見つかりません)
RegisterClassにブレークポイントを再度設定しようとしましたが、何度も呼び出され、どれが必要かを判断するのが困難でした。
最後に、LoadCursorとLoadIconにブレークポイントを設定し、ウィンドウクラス名を変更するのに適した場所を見つけました。変更
後にプログラムを実行します
。正常に変更しました。
このゲームにはファイルmd5検証があるため、ファイルアドレスがメモリアドレスによって計算された後にファイルを変更してクラス名を変更する方法はありません。したがって、私はこの考えをあきらめることができます。
要約:
RegisterClassExのブレークポイントがないため(私はRegisterClassについてのみ考えました)多くの時間が無駄になりました。インポートテーブルフックを使用して、クラス名を変更する必要性を実装できます。