Debug API写的loader(转载+整理)

   一直想做一个KeyMakerLoader,能解壳,寄存器,指定内存,通宵了一晚上基本搞定

         下面是代:

        

// 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,慢慢修改了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值