DEBUG API写简单的Loader的方法
一直想做一个类似KeyMaker的Loader,能解壳,能读寄存器,读指定内存值,通宵了一晚上基本搞定
下面是代码:
//MemoryReader.cpp:定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include"windows.h"
#include"Commdlg.h"
#include"winnt.h"
BYTEINT3=0xCC;
//写入前的
BYTEOld;
//页面属性
DWORDOldProtect;
//是否已写入INT3
boolHasINT3=false;
boolIsFirstINT3=true;
DWORDBreakPoint=0x10074B8;
BYTEOrg[8]={0x80,0x3E};
//判断是否解压完成
boolIsUnpacked(PROCESS_INFORMATIONpi)
{
SuspendThread(pi.hThread);
CONTEXTcontext;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags=CONTEXT_FULL|CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
printf("ExeInfo:Eax:%x,Esp:%x,Eip:%x ",context.Eax,context.Esp,context.Eip);
ResumeThread(pi.hThread);
BYTEmem[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("hexnumis:%x,%x,%x,%x ",mem[0],mem[1],mem[2],mem[3]);
if(mem[0]^0xff==Org[0]&&mem[1]^0xff==Org[1])
{
//不能乱调用
Old=mem[0];
returnTRUE;
}
returnfalse;
}
//写INT3
boolWriteINT3(PROCESS_INFORMATIONpi)
{
//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);
boolret=WriteProcessMemory(pi.hProcess,(LPVOID)BreakPoint,&INT3,sizeof(INT3),NULL);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,OldProtect,&OldProtect);
HasINT3=ret;
ResumeThread(pi.hThread);
returnret;
}
//改回去
boolCleanINT3(PROCESS_INFORMATIONpi)
{
//SuspendThread(pi.hThread);
boolret=WriteProcessMemory(pi.hProcess,(LPVOID)BreakPoint,&Old,sizeof(Old),NULL);
if(ret==false)
{
printf("改回去失败! ");
}
CONTEXTcontext;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags=CONTEXT_FULL|CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
context.Eip--;
SetThreadContext(pi.hThread,&context);
printf("已经改回去了,Eax:%x ",context.Eax);
returnret;
}
intmain(intargc,char*argv[])
{
charf_name[256];
f_name[0]=NULL;
OPENFILENAMEfilename;
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))
return0;
STARTUPINFOsi;
PROCESS_INFORMATIONpi;
ZeroMemory(&si,sizeof(STARTUPINFO));
ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
boolret=CreateProcess(filename.lpstrFile,"",NULL,NULL,FALSE,DEBUG_PROCESS,NULL,NULL,&si,&pi);
if(ret==false)
{
MessageBox(NULL,"创建进程失败!","",0);
return-1;
}
DEBUG_EVENTdevent;
intDllCount=0;
while(TRUE)
{
if(WaitForDebugEvent(&devent,1))
{
switch(devent.dwDebugEventCode)
{
caseCREATE_PROCESS_DEBUG_EVENT:
printf("CREATE_PROCESS_DEBUG_EVENT... ");
break;
caseCREATE_THREAD_DEBUG_EVENT:
printf("CREATE_THREAD_DEBUG_EVENT... ");
break;
caseEXCEPTION_DEBUG_EVENT:
//printf("EXCEPTION_DEBUG_EVENT... ");
switch(devent.u.Exception.ExceptionRecord.ExceptionCode)
{
caseEXCEPTION_BREAKPOINT:
if(HasINT3)
{
SuspendThread(pi.hThread);
CONTEXTcontext;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags=CONTEXT_FULL|CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
printf("Eax:%x ,Esi:%x ,Eip:%x ,Ebp:%x ",context.Eax,context.Esi,context.Eip,context.Ebp);
if(context.Eip==BreakPoint+1)
{
if(!CleanINT3(pi))
{
printf("清除断点失败!");
}
printf("ProgramStoppedAtWhatWeWant ");
charkey[256];
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,PAGE_READWRITE,&OldProtect);
ReadProcessMemory(pi.hProcess,(LPCVOID)context.Esi,key,sizeof(key),NULL);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,OldProtect,&OldProtect);
printf("读出来的东西是%s ",key);
}
ResumeThread(pi.hThread);
}
break;
caseEXCEPTION_SINGLE_STEP:
printf("2EXCEPTION_SINGLE_STEP ");
break;
caseEXCEPTION_ACCESS_VIOLATION:
printf("读写地址出错 ");
printf("%d,%x ",devent.u.Exception.ExceptionRecord.ExceptionInformation[0],devent.u.Exception.ExceptionRecord.ExceptionAddress);
ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
/*charNop[3];
Nop[0]=0x90;
Nop[1]=0x90;
Nop[2]=0x90;
PVOIDpathAddress;
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;
caseLOAD_DLL_DEBUG_EVENT:
//获取DLLNAME太复杂,暂时做不到
DllCount++;
printf("%d,ProgramLoadsaDllFromBaseImage:%x,ImageName:%x ",DllCount,devent.u.LoadDll.lpBaseOfDll,devent.u.LoadDll.lpImageName);
//
#include"stdafx.h"
#include"windows.h"
#include"Commdlg.h"
#include"winnt.h"
BYTEINT3=0xCC;
//写入前的
BYTEOld;
//页面属性
DWORDOldProtect;
//是否已写入INT3
boolHasINT3=false;
boolIsFirstINT3=true;
DWORDBreakPoint=0x10074B8;
BYTEOrg[8]={0x80,0x3E};
//判断是否解压完成
boolIsUnpacked(PROCESS_INFORMATIONpi)
{
SuspendThread(pi.hThread);
CONTEXTcontext;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags=CONTEXT_FULL|CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
printf("ExeInfo:Eax:%x,Esp:%x,Eip:%x ",context.Eax,context.Esp,context.Eip);
ResumeThread(pi.hThread);
BYTEmem[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("hexnumis:%x,%x,%x,%x ",mem[0],mem[1],mem[2],mem[3]);
if(mem[0]^0xff==Org[0]&&mem[1]^0xff==Org[1])
{
//不能乱调用
Old=mem[0];
returnTRUE;
}
returnfalse;
}
//写INT3
boolWriteINT3(PROCESS_INFORMATIONpi)
{
//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);
boolret=WriteProcessMemory(pi.hProcess,(LPVOID)BreakPoint,&INT3,sizeof(INT3),NULL);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,OldProtect,&OldProtect);
HasINT3=ret;
ResumeThread(pi.hThread);
returnret;
}
//改回去
boolCleanINT3(PROCESS_INFORMATIONpi)
{
//SuspendThread(pi.hThread);
boolret=WriteProcessMemory(pi.hProcess,(LPVOID)BreakPoint,&Old,sizeof(Old),NULL);
if(ret==false)
{
printf("改回去失败! ");
}
CONTEXTcontext;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags=CONTEXT_FULL|CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
context.Eip--;
SetThreadContext(pi.hThread,&context);
printf("已经改回去了,Eax:%x ",context.Eax);
returnret;
}
intmain(intargc,char*argv[])
{
charf_name[256];
f_name[0]=NULL;
OPENFILENAMEfilename;
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))
return0;
STARTUPINFOsi;
PROCESS_INFORMATIONpi;
ZeroMemory(&si,sizeof(STARTUPINFO));
ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
boolret=CreateProcess(filename.lpstrFile,"",NULL,NULL,FALSE,DEBUG_PROCESS,NULL,NULL,&si,&pi);
if(ret==false)
{
MessageBox(NULL,"创建进程失败!","",0);
return-1;
}
DEBUG_EVENTdevent;
intDllCount=0;
while(TRUE)
{
if(WaitForDebugEvent(&devent,1))
{
switch(devent.dwDebugEventCode)
{
caseCREATE_PROCESS_DEBUG_EVENT:
printf("CREATE_PROCESS_DEBUG_EVENT... ");
break;
caseCREATE_THREAD_DEBUG_EVENT:
printf("CREATE_THREAD_DEBUG_EVENT... ");
break;
caseEXCEPTION_DEBUG_EVENT:
//printf("EXCEPTION_DEBUG_EVENT... ");
switch(devent.u.Exception.ExceptionRecord.ExceptionCode)
{
caseEXCEPTION_BREAKPOINT:
if(HasINT3)
{
SuspendThread(pi.hThread);
CONTEXTcontext;
ZeroMemory(&context,sizeof(CONTEXT));
context.ContextFlags=CONTEXT_FULL|CONTEXT_DEBUG_REGISTERS;
GetThreadContext(pi.hThread,&context);
printf("Eax:%x ,Esi:%x ,Eip:%x ,Ebp:%x ",context.Eax,context.Esi,context.Eip,context.Ebp);
if(context.Eip==BreakPoint+1)
{
if(!CleanINT3(pi))
{
printf("清除断点失败!");
}
printf("ProgramStoppedAtWhatWeWant ");
charkey[256];
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,PAGE_READWRITE,&OldProtect);
ReadProcessMemory(pi.hProcess,(LPCVOID)context.Esi,key,sizeof(key),NULL);
VirtualProtectEx(pi.hProcess,(LPVOID)BreakPoint,1,OldProtect,&OldProtect);
printf("读出来的东西是%s ",key);
}
ResumeThread(pi.hThread);
}
break;
caseEXCEPTION_SINGLE_STEP:
printf("2EXCEPTION_SINGLE_STEP ");
break;
caseEXCEPTION_ACCESS_VIOLATION:
printf("读写地址出错 ");
printf("%d,%x ",devent.u.Exception.ExceptionRecord.ExceptionInformation[0],devent.u.Exception.ExceptionRecord.ExceptionAddress);
ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
/*charNop[3];
Nop[0]=0x90;
Nop[1]=0x90;
Nop[2]=0x90;
PVOIDpathAddress;
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;
caseLOAD_DLL_DEBUG_EVENT:
//获取DLLNAME太复杂,暂时做不到
DllCount++;
printf("%d,ProgramLoadsaDllFromBaseImage:%x,ImageName:%x ",DllCount,devent.u.LoadDll.lpBaseOfDll,devent.u.LoadDll.lpImageName);
本文地址:http://www.45fan.com/dnjc/70798.html