[C++] 纯文本查看 复制代码
//用于储存主线程的句柄储存
HANDLE main_tread;
//线程遍历函数
void PrintThreadsOfProcess(DWORD processID) {
THREADENTRY32 te32;
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
// 创建线程快照
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE) {
MessageBox(0, "CreateToolhelp32Snapshot error", "⑨", 0);
return;
}
te32.dwSize = sizeof(THREADENTRY32);
// 遍历快照中的第一个线程,开始遍历
if (!Thread32First(hThreadSnap, &te32)) {
MessageBox(0, "Thread32First error", "⑨", 0);
CloseHandle(hThreadSnap);
return;
}
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_ALL;
char buffer[20];
do {
if (te32.th32OwnerProcessID == processID) {
//strcpy(buffer, "");
//sprintf(buffer, "ThreadID:%d", te32.th32ThreadID);
//MessageBox(0, buffer, "⑨", 0);
//这三行是因为当时一直没有成功,程序直接退出,我不知道自己代码是否正确,用来验证的,成功就注销了
//获取线程的寄存器状态,其中ys主要是在调试时我来判断获取是否出错的,没有其他用处
BOOL ys = GetThreadContext(OpenThread(PROCESS_ALL_ACCESS, true, te32.th32ThreadID), &ctx);
ctx.Dr7 = (DWORD)0x1;
ctx.Dr0 = (DWORD)0x00401053; //断点位置
SetThreadContext(OpenThread(PROCESS_ALL_ACCESS, true, te32.th32ThreadID), &ctx);
//当时程序直接运行报错我以为是因为我全部线程下硬断哪里出问题了,根据隔壁的测试大概总结:一般获取的第一个线程id就是主线程,所以这里执行一次直接退出,相当于只修改主线程
break;
}
} while (Thread32Next(hThreadSnap, &te32));
CloseHandle(hThreadSnap);
}
//线程函数,用来检测程序是否解压完毕
DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter)
{
byte byteRead = 0;
while (true) //循环读取目标位置,查看目标位置是否已经解压完毕
{
ReadProcessMemory(main_tread, (LPCVOID)0x00401053, &byteRead, 1, NULL);
if (byteRead == 0x0F) //代表程序已经解压完毕了,退出检测循环
break;
byteRead = 0;
Sleep(100);
}
PrintThreadsOfProcess(GetCurrentProcessId()); //调用函数下硬件断点
MessageBox(0, "线程感觉到程序已解压,设置硬件断点完毕", "⑨", 0);
ExitThread(NULL);
}
//异常处理
DWORD NTAPI ExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
//0x00401053
if ((DWORD)pExceptionInfo->ExceptionRecord->ExceptionAddress == 0x00401053)
{
MessageBox(0, "发现硬件断点,尝试将eip向后移动", "⑨", 0);
pExceptionInfo->ContextRecord->Eip += 6; //指令向后移动一位
return EXCEPTION_CONTINUE_EXECUTION; //回到产生异常的位置
}
return EXCEPTION_CONTINUE_SEARCH; //不是需要的报错位置,交给下一个异常处理器
}
//dll的入口函数
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
main_tread = OpenProcess(PROCESS_ALL_ACCESS, true, GetCurrentProcessId());
//注册异常函数
AddVectoredContinueHandler(NULL, (PVECTORED_EXCEPTION_HANDLER)ExceptionHandler);
//创造监视线程
CreateThread(NULL,NULL,ThreadProc,NULL,NULL,NULL);
g_hCurrentModule = hModule;
DisableThreadLibraryCalls(hModule);
if (!NsLoad())
return FALSE;
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}