[C++] 纯文本查看 复制代码
// MemoryReader.cpp : 定义控制台应用程序的入口点。
// AntiDebug:IsDebugPresent如何避开?
// 加壳处理不完善//
#include "stdafx.h"
#include "windows.h"
#include "Commdlg.h"
#include "winnt.h"
BYTE INT3 = 0xCC;
//写入前的
BYTE Old;
//页面属性
DWORD OldProtect;
//是否已写入INT3
bool HasINT3 = false;
bool IsFirstINT3 = true;
DWORD BreakPoint = 0x00452191;
BYTE Org[8] = {0xE8,0x4E};
//判断是否解压完成
bool IsUnpacked(PROCESS_INFORMATION pi)
{
SuspendThread(pi.hThread);
CONTEXT context;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
printf("Exe Info:Eax:%x,Esp:%x,Eip:%x\n",context.Eax,context.Esp,context.Eip);
ResumeThread(pi.hThread);
BYTE mem[8];
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,PAGE_READWRITE, &OldProtect);
ReadProcessMemory(pi.hProcess,(LPCVOID)BreakPoint,&mem,8,NULL);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,OldProtect,&OldProtect);
printf("hex num is:%x,%x,%x,%x\n",mem[0],mem[1],mem[2],mem[3]);
if(mem[0] ^ 0xff == Org[0] && mem[1] ^ 0xff == Org[1])
{
//不能乱调用
Old = mem[0];
return TRUE;
}
return false;
}
//写INT3
bool WriteINT3(PROCESS_INFORMATION pi)
{
//VirtualAllocEx(pi.hProcess,(LPVOID)0x0101259b,sizeof(INT3), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
SuspendThread(pi.hThread);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,PAGE_READWRITE, &OldProtect);
bool ret = WriteProcessMemory(pi.hProcess,(LPVOID)BreakPoint,&INT3,sizeof(INT3),NULL);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,OldProtect,&OldProtect);
HasINT3 = ret;
ResumeThread(pi.hThread);
return ret;
}
//改回去
bool CleanINT3(PROCESS_INFORMATION pi)
{
//SuspendThread(pi.hThread);
bool ret = WriteProcessMemory(pi.hProcess,(LPVOID)BreakPoint,&Old,sizeof(Old),NULL);
if(ret == false)
{
printf("改回去失败!\n");
}
CONTEXT context;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
context.Eip--;
SetThreadContext(pi.hThread,&context);
printf("已经改回去了,Eax:%x\n",context.Eax);
return ret;
}
//隐藏Debug
void HideDebug(PROCESS_INFORMATION pi)
{
BYTE ISDEBUGFLAG = 0x00;
int ISHEAPFLAG = 2;
SuspendThread(pi.hThread);
CONTEXT context;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
//IsDebugPresent_Flag
WriteProcessMemory(pi.hProcess,(LPVOID)(context.Ebx+0x2),&ISDEBUGFLAG,1,NULL);
//NTGlobal_Flag 用0D则为70 这个为0 防止其他调试器存在
WriteProcessMemory(pi.hProcess,(LPVOID)(context.Ebx+0x68),&ISDEBUGFLAG,1,NULL);
//GetProcessHeap_Flag
DWORD HeapAddress;
ReadProcessMemory(pi.hProcess,(LPCVOID)(context.Ebx + 0x18),&HeapAddress,sizeof(HeapAddress),NULL);
WriteProcessMemory(pi.hProcess,(LPVOID)HeapAddress,&ISHEAPFLAG,sizeof(ISHEAPFLAG),NULL);
ReadProcessMemory(pi.hProcess,(LPCVOID)(context.Ebx + 0x68),&ISDEBUGFLAG,1,NULL);
printf("NT_GLOBAL=%d\n",ISDEBUGFLAG);
ResumeThread(pi.hThread);
}
int main(int argc, char* argv[])
{
char f_name[256];
f_name[0] = NULL;
OPENFILENAME filename;
ZeroMemory(&filename,sizeof(OPENFILENAME));
filename.lStructSize = sizeof(OPENFILENAME);
filename.hwndOwner = NULL;
filename.lpstrFilter = "*.exe";
filename.lpstrFile = f_name;
filename.nMaxFile = 256;
filename.lpstrInitialDir = NULL;
filename.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
if(!GetOpenFileName(&filename))
return 0;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(STARTUPINFO));
ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
bool ret = CreateProcess(filename.lpstrFile,"",NULL,NULL,FALSE,DEBUG_PROCESS,NULL,NULL,&si,&pi);
if(ret == false)
{
MessageBox(NULL,"创建进程失败!","",0);
return -1;
}
//Anti-Anti-Debug
HideDebug(pi);
DEBUG_EVENT devent;
int DllCount = 0;
while(TRUE)
{
if(WaitForDebugEvent(&devent,1))
{
switch(devent.dwDebugEventCode)
{
case CREATE_PROCESS_DEBUG_EVENT:
printf("CREATE_PROCESS_DEBUG_EVENT\n");
break;
case CREATE_THREAD_DEBUG_EVENT:
printf("CREATE_THREAD_DEBUG_EVENT\n");
break;
case EXCEPTION_DEBUG_EVENT:
//printf("EXCEPTION_DEBUG_EVENT\n");
switch(devent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
if(HasINT3)
{
SuspendThread(pi.hThread);
CONTEXT context;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
printf("Eax:%x\n,Esi:%x\n,Eip:%x\n,Ebp:%x\n",context.Eax,context.Esi,context.Eip,context.Ebp);
if(context.Eip == BreakPoint + 1)
{
if(!CleanINT3(pi))
{
printf("清除断点失败!");
}
printf("Program Stopped At What We Want\n");
char key[256];
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,PAGE_READWRITE, &OldProtect);
ReadProcessMemory(pi.hProcess,(LPCVOID)context.Edx,key,sizeof(key),NULL);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,OldProtect,&OldProtect);
printf("读出来的东西是 %s\n",key);
}
ResumeThread(pi.hThread);
}
break;
case EXCEPTION_SINGLE_STEP:
printf("2 EXCEPTION_SINGLE_STEP\n");
break;
case EXCEPTION_ACCESS_VIOLATION:
printf("读写地址出错\n");
printf("%d,%x\n",devent.u.Exception.ExceptionRecord.ExceptionInformation[0],devent.u.Exception.ExceptionRecord.ExceptionAddress);
ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
/* char Nop[3];
Nop[0] = 0x90;
Nop[1] = 0x90;
Nop[2] = 0x90;
PVOID pathAddress;
pathAddress = devent.u.Exception.ExceptionRecord.ExceptionAddress;
VirtualProtectEx(pi.hProcess,pathAddress,3,PAGE_READWRITE, &OldProtect);
WriteProcessMemory(pi.hProcess,pathAddress,Nop,3,NULL);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,OldProtect,&OldProtect);
ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_EXCEPTION_NOT_HANDLED); */
break;
default:
break;
}
break;
case LOAD_DLL_DEBUG_EVENT:
//获取DLL NAME太复杂,暂时做不到
DllCount ++;
printf("%d,Program Loads a Dll From BaseImage:%x,ImageName:%x\n",DllCount,devent.u.LoadDll.lpBaseOfDll,devent.u.LoadDll.lpImageName);
if(!HasINT3)
{
if(IsUnpacked(pi))
{
printf("UnPacked Success!!\n");
WriteINT3(pi);
printf("Write a INT3\n");
}
}
break;
case UNLOAD_DLL_DEBUG_EVENT:
printf("UnLoad a Dll From BaseImage:%x,ImageName:%x\n",devent.u.LoadDll.lpBaseOfDll,devent.u.LoadDll.lpImageName);
if(!HasINT3)
{
if(IsUnpacked(pi))
{
printf("UnPacked Success!!\n");
WriteINT3(pi);
printf("Write a INT3\n");
}
}
break;
case OUTPUT_DEBUG_STRING_EVENT:
break;
case EXIT_PROCESS_DEBUG_EVENT:
printf("调试程序已退出");
break;
default:
printf("%d\n",devent.dwDebugEventCode);
break;
}
ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_CONTINUE);
}
else
{
}
}
//KeyMake中不要这两句
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}