好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 liyangjida 于 2017-2-3 09:47 编辑
哈哈,那我就上源码了啊,用了一些反调试的技术,在定时器中动态判断是否处于调试状态。设置debugFlag,判断调试汇编代码:
push eax;
mov eax, dword ptr fs : [0x30];
movzx eax, byte ptr ds : [eax + 2];
mov debugFlag, eax;
pop eax;
然后两个unicode字符数组,一个用于debug状态混淆,另一个才是正确的。
wchar_t* rightbuff = debugFlag ? dstBuff2 : dstBuff1;
wchar_t dstBuff1[11] = {0xffcd, 0xffcf, 0xffce, 0xffc8, 0xa18b, 0x9a4f, 0xa18b, 0xa014, 0xb1af, 0x00fe, 0x0000};
是正确的。
为了防止被字符串搜索到,只做了简单的取反加密,所以再把dstBuff1取反,就得到正确的unicode数组:
32 00 30 00 31 00 37 00 74 5e b0 65 74 5e eb 5f 50 4e 01 ff 00 00
2017年新年快乐!
[C++] 纯文本查看 复制代码 #include <Windows.h>
#include "resource.h"
#include <winternl.h>
int debugFlag = 1;
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_TIMER:
__asm
{
push eax;
mov eax, dword ptr fs : [0x30];
movzx eax, byte ptr ds : [eax + 2];
mov debugFlag, eax;
pop eax;
}
break;
case WM_SHOWWINDOW:
SetTimer(hwnd, 1, 500, NULL);
break;
case WM_CLOSE:
EndDialog(hwnd, 0);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BUTTON1:
int len = SendMessage(GetDlgItem(hwnd, IDC_EDIT1), WM_GETTEXTLENGTH, 0, 0);
wchar_t* buff = new wchar_t[len + 1];
wchar_t dstBuff1[11] = {0xffcd, 0xffcf, 0xffce, 0xffc8, 0xa18b, 0x9a4f, 0xa18b, 0xa014, 0xb1af, 0x00fe, 0x0000};
wchar_t dstBuff2[11] = {0xffaa, 0xffc8, 0xfa1b, 0xfe00, 0xf4a9, 0xecff, 0xfa1b, 0xef11, 0xf4a9, 0xecdd, 0x0000};
wchar_t* rightbuff = debugFlag ? dstBuff2 : dstBuff1;
SendMessage(GetDlgItem(hwnd, IDC_EDIT1), WM_GETTEXT, len + 1, (LPARAM)buff);
char* charBuff = (char*)buff;
for (int i = 0; i < 2 * len; ++i)
{
charBuff[i] = ~charBuff[i];
}
if (memcmp(buff, rightbuff, len) == 0 && len > 0)
{
MessageBox(hwnd, L"恭喜,破解成功", L"消息", MB_OK);
}
else
{
MessageBox(hwnd, L"请输入正确的密码", L"消息", MB_OK);
}
break;
}
break;
default:
break;
}
return S_OK;
}
int WINAPI WinMain(HINSTANCE hInstace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
DialogBox(hInstace, MAKEINTRESOURCEW(IDD_DIALOG1), NULL, (DLGPROC)MainWndProc);
}
|
|