DEBUG API写简单的Loader

         一直想做一个类似KeyMaker的Loader,能解壳,能读寄存器,读指定内存值,通宵了一晚上基本搞定

         下面是代码:

        

//  MemoryReader.cpp : 定义控制台应用程序的入口点。
//

#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 
=   0x10074B8 ;

BYTE Org[
8 =   {0x80,0x3E} ;

// 判断是否解压完成
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 ",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 ",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(
"改回去失败! ");
    }

    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 ",context.Eax);
    
return ret;
}




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;
    }

    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... ");
                
break;
            
case CREATE_THREAD_DEBUG_EVENT:
                printf(
"CREATE_THREAD_DEBUG_EVENT... ");
                
break;
            
case EXCEPTION_DEBUG_EVENT:
                
//printf("EXCEPTION_DEBUG_EVENT... ");
                 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 ,Esi:%x ,Eip:%x ,Ebp:%x ",context.Eax,context.Esi,context.Eip,context.Ebp); 
                        
if(context.Eip == BreakPoint + 1)
                        
{
                            
if(!CleanINT3(pi))
                            
{
                                printf(
"清除断点失败!");
                            }


                            printf(
"Program Stopped At What We Want ");
                            
char key[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;
                
case EXCEPTION_SINGLE_STEP:
                    printf(
"2 EXCEPTION_SINGLE_STEP ");
                    
break;
                
case EXCEPTION_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);

/*                    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 ",DllCount,devent.u.LoadDll.lpBaseOfDll,devent.u.LoadDll.lpImageName);                
                
if(!HasINT3)
                
{
                  
if(IsUnpacked(pi))
                  
{
                      printf(
"UnPacked Success!! ");
                      WriteINT3(pi);
                      printf(
"Write a INT3 ");
                  }

                }

                
break;
            
case UNLOAD_DLL_DEBUG_EVENT:
                printf(
"UnLoad a Dll From BaseImage:%x,ImageName:%x ",devent.u.LoadDll.lpBaseOfDll,devent.u.LoadDll.lpImageName);                
                
if(!HasINT3)
                
{
                  
if(IsUnpacked(pi))
                  
{
                      printf(
"UnPacked Success!! ");
                      WriteINT3(pi);
                      printf(
"Write a INT3 ");
                  }

                }

                
break;
                
break;
            
case OUTPUT_DEBUG_STRING_EVENT:
                
break;
            
case EXIT_PROCESS_DEBUG_EVENT:
                printf(
"调试程序已退出");
                
break;
            
default:
                printf(
"%d ",devent.dwDebugEventCode);
                
break;
            }

            ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_CONTINUE);
        }

        
else
        
{
        }

    }

    
//KeyMake中不要这两句
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    
return 0;
}


           可以解压缩和加密壳,不过必须是要获得的内容是壳执行之后,如果再壳执行之前有内容的话可能会被壳偷掉,另外还不支持AntiDebug,不过测试Keymake也不支持AntiDebug,慢慢修改了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值