看雪早就有蒙泰5.0电子版全版,
该文章介绍于http://www.pediy.com/bbshtml/BBS4/kanxue109.htm
小弟不才 ,发现一个重要问题,该版软件有一个很大的暗桩,就是这个软件居然还是电子版纹设计软件,属于防伪设计的。市面价格28万。去买的话,他们销售会反馈10万的回扣(这就是国产软件的猫腻)。主要用于小型印刷中心和有防伪印刷需求的中小公司。
它是插不同的狗 表现为不同的软件版本。
其中版纹是藏的最深的一个暗桩。
其它的电子版各个版本都属于便宜货。
=======================================================
站在前人的肩膀上:
关键点:
00436BCA |. 85C0 TEST EAX,EAX
00436BCC |. 74 34 JE SHORT Out.00436C02
00436BCE |. 68 503C7D5A PUSH 5A7D3C50 ; /Arg5 = 5A7D3C50
00436BD3 |. 8D8D FCFDFFFF LEA ECX,DWORD PTR SS:[EBP-204] ; |
00436BD9 |. 51 PUSH ECX ; |Arg4
00436BDA |. 8D85 F4FDFFFF LEA EAX,DWORD PTR SS:[EBP-20C] ; |
00436BE0 |. 50 PUSH EAX ; |Arg3
00436BE1 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] ; |
00436BE4 |. 52 PUSH EDX ; |Arg2
00436BE5 |. 8D8D F8FDFFFF LEA ECX,DWORD PTR SS:[EBP-208] ; |
00436BEB |. 51 PUSH ECX ; |Arg1
00436BEC |. E8 BD271A00 CALL DTPW.EXE.005D93AE ; \DTPW.EXE.005D93AE
最关键的点是
LEA ECX,DWORD PTR SS:[EBP-204]
中的(EBP-204)指向内存中的数据,根据有狗或者无狗 反复查看判断,这个点的数据非常关键(事后证明也就是这个关键点),
无狗数据: {0x70,0x37,0xd3,0x00,0x00,0x00,0xD2,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
有狗数据: {0x30,0x43,0x8E,0x24,0xD4,0xA6,0xC6,0x6C,0xCA,0xB6,0xC3,0xA7,0xBD,0x98,0xC9,0xC9};
然后在 00436BEC |. E8 BD271A00 CALL Out.005D93AE ; \Out.005D93AE
所以在soft-ice中 幸亏的把数据手写到纸片上,然后把数据在辛苦的添到ebp-204指向的内存 ,运行
嘻嘻 无狗也是蒙泰版纹。
最后看了看没有合适的内存补丁软件,最后自己写了个VC的程序 其中利用 Debug Api。
程序很长时间没有维护了,所以很乱。大家慢慢看。
#include "windows.h"
HINSTANCE GhInstance;
//HANDLE MutexHandle;
STARTUPINFO gstStartUp;
PROCESS_INFORMATION gpsInfo;
DEBUG_EVENT gDBEvent;
CONTEXT gContext;
DWORD dwIdOld;
//BYTE buffer[2]={0x90,0x90};
//BYTE MYEIP1CODE[5]={0XE8,0X4F,0X00,0X00,0X00};//call xxxx
//BYTE MYEIP2CODE[2]={0x74,0x34};//jz +34
BYTE INT3CODE[1]={0XCC};
BYTE OldCodeBca[2]={0x85,0xC0};//test eax,eax
//BYTE StartCode[1]={0xa1};
unsigned long StartEip=0x00401000;// 0xa1=>cc
unsigned long MyEip1=0x00669E00;
unsigned long MyEip2=0x00436BCA;
unsigned long MyEip3=0x014dfdb0; //ebp-204// 98 is 0x014bfd94
long DoSth=0;
//BYTE TarGetData[16]={0x70,0x37,0xd3,0x00,0x00,0x00,0xD2,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
BYTE WriteData[16]={0x30,0x43,0x8E,0x24,0xD4,0xA6,0xC6,0x6C,0xCA,0xB6,0xC3,0xA7,0xBD,0x98,0xC9,0xC9};
BYTE ReadCodeData[128];
BYTE ReadBuffer[10];
char szFileName[20]={".\\out.exe"}; // 目标文件名 Path.dat
long LastErrorCode;
char LpErrorText[40];
char LpDesCripeText[2048];
bool WhileDoFlag;
bool LoaderBkFlag;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
GhInstance=hInstance;
SetLastError(0);
GetStartupInfo(&gstStartUp);
if (CreateProcess(szFileName,NULL,NULL,NULL,FALSE,DEBUG_ONLY_THIS_PROCESS,0,0,&gstStartUp,&gpsInfo)==0)
{
LastErrorCode=GetLastError();
wsprintf(LpErrorText,"创建Dun-packed.exe失败,检查目标程序是否存在ErrorCode=%2d",LastErrorCode);
MessageBox(NULL,LpErrorText,"",MB_ICONERROR);
return 0;
}
WhileDoFlag=true;
SetLastError(0);
while(WhileDoFlag)//调试循环
{
WaitForDebugEvent(&gDBEvent,INFINITE);
gContext.ContextFlags=CONTEXT_FULL;
GetThreadContext(gpsInfo.hThread,&gContext);
LastErrorCode=GetLastError();
switch(gDBEvent.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT://1debug 事件
if (gDBEvent.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT)//断点
{
if (LoaderBkFlag==true)//第一次断点
{
gContext.ContextFlags= CONTEXT_FULL;
GetThreadContext(gpsInfo.hThread,&gContext);
gContext.Dr0=MyEip2;
gContext.Dr7=0x0000-0000;
SetThreadContext(gpsInfo.hThread,&gContext);
//gContext.EFlags=gContext.EFlags | 0x100;//or regFlag,100h
//SetThreadContext(gpsInfo.hThread,&gContext);
//VirtualProtectEx(gpsInfo.hProcess,(void *)gContext.Eip,50,PAGE_READWRITE,&dwIdOld);
//VirtualProtectEx(hProcess, lpAddr, 1, dwOldProt, &dwNewProt);
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"GVirtualProtectEx出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"出错",MB_OK);
}
//ReadProcessMemory(gpsInfo.hProcess,(void *)StartEip,&ReadCodeData,sizeof(ReadCodeData),NULL);
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"ReadProcessMemory出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"出错",MB_OK);
}
//wsprintf(LpDesCripeText,"补丁结果Eip=%4x,Code=%x %x %x
%x",gContext.Eip,ReadCodeData[0],ReadCodeData[1],ReadCodeData[2],ReadCodeData[3]);
//MessageBox(0,LpDesCripeText,"第一次中断!",MB_OK);
LoaderBkFlag=false;
DoSth=1;
}
else if (LoaderBkFlag==false)
{
if (DoSth==1 && gContext.Eip==(MyEip2+1))
{
ReadProcessMemory(gpsInfo.hProcess,(void
*)gContext.Eip,&ReadCodeData,sizeof(ReadCodeData),NULL);
//wsprintf(LpDesCripeText,"Before Path
Eip=%4x,Code=%02x%02x%02x%02x",gContext.Eip,ReadCodeData[0],ReadCodeData[1],ReadCodeData[2],ReadCodeData[3]);
//MessageBox(0,LpDesCripeText,"第2次中断!",MB_OK);
gContext.Eip--;
gContext.Eax=1;
//gContext.Eax=1;
VirtualProtectEx(gpsInfo.hThread,(void
*)StartEip,10000L,PAGE_EXECUTE_READWRITE,&dwIdOld);
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"蒙泰版纹共享版\r\n此版本只能用在学习、研究之用不能用于商
业目的\r\n调试信息VirtualProtectEx出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"中国共享软件联盟",MB_OK);
}
WriteProcessMemory(gpsInfo.hProcess,(void *)gContext.Eip,&OldCodeBca,2,0);//修补
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"修补WriteProcessMemory出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"出错",MB_OK);
}
//WriteProcessMemory(gpsInfo.hProcess,(void *)(MyEip2),&INT3CODE,1,0);//path 2
//------------------------------------
MyEip3=(((gContext).Ebp)-0x204);
VirtualProtectEx(gpsInfo.hProcess,(void *)(MyEip3),20L,PAGE_READWRITE,&dwIdOld);
LastErrorCode=GetLastError();
ReadProcessMemory(gpsInfo.hProcess,(void *)(MyEip3),&ReadCodeData,16,NULL);
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"path WriteProcessMemory出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"出错",MB_OK);
}
//wsprintf(LpDesCripeText,"第2次内存存储前:
Eip=%4x,Code=%02x%02x%02x%02x",(gContext.Ebp-204),ReadCodeData[0],ReadCodeData[1],ReadCodeData[2],ReadCodeData[3]);
//MessageBox(0,LpDesCripeText,"第2次内存!",MB_OK);
//...................................
WriteProcessMemory(gpsInfo.hProcess,(void *)(MyEip3),&WriteData,16,0);//path Data
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"path WriteProcessMemory出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"出错",MB_OK);
}
ReadProcessMemory(gpsInfo.hProcess,(void
*)(MyEip3),&ReadCodeData,sizeof(ReadCodeData),NULL);
//wsprintf(LpDesCripeText,"第2次内存结果
Eip=%4x,Code=%02x%02x%02x%02x",(gContext.Ebp-204),ReadCodeData[0],ReadCodeData[1],ReadCodeData[2],ReadCodeData[3]);
//MessageBox(0,LpDesCripeText,"第2次内存结果!",MB_OK);
SetThreadContext(gpsInfo.hThread,&gContext);
ReadProcessMemory(gpsInfo.hProcess,(void
*)gContext.Eip,&ReadCodeData,sizeof(ReadCodeData),NULL);
//wsprintf(LpDesCripeText,"第2次补丁结果
Eip=%4x,Code=%02x%02x%02x%02x",gContext.Eip,ReadCodeData[0],ReadCodeData[1],ReadCodeData[2],ReadCodeData[3]);
//MessageBox(0,LpDesCripeText,"第2次中断!",MB_OK);
DoSth=2;
}
//}
}
ContinueDebugEvent(gDBEvent.dwProcessId,gDBEvent.dwThreadId, DBG_CONTINUE);
}
else if (gDBEvent.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP)
{
gContext.ContextFlags= CONTEXT_FULL;
GetThreadContext(gpsInfo.hThread,&gContext);
ReadProcessMemory(gpsInfo.hProcess,(void *)gContext.Eip,&ReadCodeData,sizeof(ReadCodeData),NULL);
wsprintf(LpDesCripeText,"单步跟踪 Eip=%4x,Code=%02x %02x %02x
%02x",gContext.Eip,ReadCodeData[0],ReadCodeData[1],ReadCodeData[2],ReadCodeData[3]);
if (gContext.Eip==MyEip1)
{
ReadProcessMemory(gpsInfo.hProcess,(void *)MyEip2,&ReadBuffer,sizeof(ReadBuffer),NULL);
//VirtualProtectEx(gpsInfo.hProcess,(void *)MyEip1,5,PAGE_READWRITE,&dwIdOld);
//修改所属进程中MessageBoxA的前5个字节的属性为可写
MessageBox(0,LpDesCripeText,"单步跟踪!",MB_OK);
MessageBox(0,"找到myEip1","找到",MB_OK);
}
else
{
gContext.EFlags=gContext.EFlags | 0x100;//or regFlag,100h
SetThreadContext(gpsInfo.hThread,&gContext);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_CONTINUE);
}
//end if
}
else if (gDBEvent.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_ACCESS_VIOLATION)
{
gContext.ContextFlags=CONTEXT_FULL;
GetThreadContext(gpsInfo.hProcess,&gContext);
GetThreadContext(gpsInfo.hThread,&gContext);
MessageBox(0,"内存访问违例","提示",MB_ICONERROR);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_CONTINUE);
}
else
{
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_CONTINUE);
}
break;
case CREATE_THREAD_DEBUG_EVENT://2
//wsprintf(LpDesCripeText,"线程创建事件 Eip=%4x",gContext.Eip);
//MessageBox(0,LpDesCripeText,"CREATE_THREAD_DEBUG_EVENT 线程创建事件",MB_OK);
gContext.ContextFlags=CONTEXT_FULL;
gpsInfo.hThread=gDBEvent.u.CreateThread.hThread;
GetThreadContext(gpsInfo.hThread,&gContext);
//VirtualProtectEx(gpsInfo.hProcess,(void *)(MyEip2),20L,PAGE_READWRITE,&dwIdOld);
//WriteProcessMemory(gpsInfo.hProcess,(void *)(MyEip2),&INT3CODE,16,0);//insert int 3
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
break;
case CREATE_PROCESS_DEBUG_EVENT://创建进程事件3
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"GVirtualProtectEx出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"出错",MB_OK);
}
//ReadProcessMemory(gpsInfo.hProcess,(void *)StartEip,&ReadBuffer,sizeof(ReadBuffer),0);
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"ReadProcessMemory出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"出错",MB_OK);
}
LoaderBkFlag=true;
//wsprintf(LpDesCripeText,"第一次写入int 3h(cc) Eip=%4x
Code=%02x%02x%02x%02x%02x%02x",gContext.Eip,ReadBuffer[0],ReadBuffer[1],ReadBuffer[2],ReadBuffer[3],ReadBuffer[4],ReadBuffer[5]);
//WriteProcessMemory(gpsInfo.hProcess,(void *)MyEip2,&INT3CODE,1,0);
if ((LastErrorCode=GetLastError())!=0)
{
wsprintf(LpErrorText,"WriteProcessMemory出错了=%d",LastErrorCode);
MessageBox(0,LpErrorText,"出错",MB_OK);
}
//MessageBox(0,LpDesCripeText,"CREATE_PROCESS_DEBUG_EVENT_进程创建事件",MB_OK);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
break;
case EXIT_THREAD_DEBUG_EVENT: //4.
//wsprintf(LpDesCripeText,"退出 线程 事件 Eip=%4x",gContext.Eip);
//MessageBox(0,LpDesCripeText,"EXIT_THREAD_DEBUG_EVENT 事件",MB_OK);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
break;
case EXIT_PROCESS_DEBUG_EVENT: //5.退出事件
//wsprintf(LpDesCripeText,"退出进程事件 Eip=%4x",gContext.Eip);
//MessageBox(0,LpDesCripeText,"EXIT_PROCESS_DEBUG_EVENT 事件",MB_OK);
WhileDoFlag=false;
break;
case LOAD_DLL_DEBUG_EVENT: //6.
//wsprintf(LpDesCripeText,"加载Dll debug 事件Eip=%4x",gContext.Eip);
//MessageBox(0,LpDesCripeText,"LOAD_DLL_DEBUG_EVENT 事件",MB_OK);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
break;
case UNLOAD_DLL_DEBUG_EVENT: //7.
//wsprintf(LpDesCripeText,"卸下dll debug事件 Eip=%4x",gContext.Eip);
//MessageBox(0,LpDesCripeText,"UNLOAD_DLL_DEBUG_EVENT 事件",MB_OK);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
break;
case OUTPUT_DEBUG_STRING_EVENT: //8.
//wsprintf(LpDesCripeText,"Eip=%4x",gContext.Eip);
//MessageBox(0,LpDesCripeText,"OUTPUT_DEBUG_STRING_EVENT 事件",MB_OK);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
break;
case RIP_EVENT: //9.
//wsprintf(LpDesCripeText,"Eip=%4x",gContext.Eip);
//MessageBox(0,LpDesCripeText,"RIP_EVENT 事件",MB_OK);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
break;
default:
//gContext.ContextFlags= CONTEXT_FULL;
// GetThreadContext(gDBEvent.u.CreateProcessInfo.hThread,&gContext);
//if (gContext.Eip==MyEip1)
// {
// MessageBeep(MB_OK);
MessageBox(0,"default处理 异常","调试程序",MB_OK);
// }
//ReadProcessMemory(gpsInfo.hProcess,(void *)gContext.Eip,&ReadBuffer,sizeof(ReadBuffer),0);
ContinueDebugEvent(gDBEvent.dwProcessId, gDBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
}//endswitch
}//.end while
/*
#define EXCEPTION_DEBUG_EVENT 1
#define CREATE_THREAD_DEBUG_EVENT 2
#define CREATE_PROCESS_DEBUG_EVENT 3
#define EXIT_THREAD_DEBUG_EVENT 4
#define EXIT_PROCESS_DEBUG_EVENT 5
#define LOAD_DLL_DEBUG_EVENT 6
#define UNLOAD_DLL_DEBUG_EVENT 7
#define OUTPUT_DEBUG_STRING_EVENT 8
#define RIP_EVENT 9
*/
return 0; //Winmain Return
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)