Programming 版 (精华区)

发信人: pzc (不过如此), 信区: Programming
标  题: PEGame
发信站: 哈工大紫丁香 (2002年03月14日15:10:45 星期四), 站内信件

***************************************************
pegame.asm在masm32v6下编译通过,为全部注入PE的代码
test.cpp在vc6下编译通过,代码插入程序
****仅供学习之用
***************************************************
;filename:  pegame.asm
.386
.model flat,stdcall
option casemap : none
include \masm32\include\windows.inc
sSEH struct
        OrgEsp            DD 0
        OrgEbp            DD 0
        SaveEip           DD 0
sSEH ends
MIN_KERNEL_SEARCH_BASE  equ 070000000h
MAX_API_STRING_LENGTH   equ 150
_DATA segment DWORD public use32 'DATA'
assume ds:_DATA, ss:_DATA
public Loader_ASM, Loader_ASMEND,Loader_DATAS
Loader_ASM:
        assume  fs:NOTHING
        pushad
        call    START
START:
        pop     ebp
        sub     ebp, offset START
        push    [esp+020h]
        call    GetKernelBase
        or      eax, eax
        jz      QUIT
        mov     [ebp+dwKernelBase], eax
; collect all API's addresses needed here
        lea     eax,[ebp+offset szLoadLibrary]
        push    eax
        push    [ebp+dwKernelBase]
        call    GetProcAddr
        or      eax, eax
        jz      QUIT
        mov     [ebp+_LoadLibrary], eax
        lea     eax,[ebp+offset szGetProcAddress]
        push    eax
        push    [ebp+dwKernelBase]
        call    GetProcAddr
        or      eax, eax
        jz      QUIT
        mov     [ebp+_GetProcAddress], eax
        lea     eax,[ebp+offset szExitProcess]
        push    eax
        push    [ebp+dwKernelBase]
        call    GetProcAddr
        or      eax, eax
        jz      QUIT
        mov     [ebp+_ExitProcess], eax
        lea     eax,[ebp+offset szUser32]
        push    eax
        call    [ebp+_LoadLibrary]
        or      eax, eax
        jz      QUIT
        mov     [ebp+dwUserBase], eax
        lea     eax,[ebp+offset szMessageBox]
        push    eax
        push    [ebp+dwUserBase]
        call    GetProcAddr
        or      eax, eax
        jz      QUIT
        mov     [ebp+_MessageBox], eax
; here is the actual code that executes like a normal prog (in the
section)
        lea     eax, [ebp+offset szMessage]
        push    MB_ICONINFORMATION or MB_SYSTEMMODAL
        push    eax
        push    eax
        push    0
        call    [ebp+_MessageBox]
QUIT:
        mov     eax, [ebp+dwOriginEntryPoint]
        mov     [esp+1ch], eax
        popad
        call    eax
; returns NULL in the case of an error
GetKernelBase:
        mov     edi, [esp+4]
        lea     eax, [ebp+offset SehHandler]
        push    eax
        push    DWORD ptr fs:[0]
        lea     eax, [ebp+offset SEH]
        assume  eax:ptr sSEH
        mov     [eax].OrgEsp, esp
        mov     [eax].OrgEbp, ebp
        lea     ebx, [ebp+offset ExceptCont]
        mov     [eax].SaveEip, ebx
        mov     fs:[0], esp
        assume  eax:NOTHING
        ; start the search
        and     edi, 0ffff0000h         ; wipe the LOWORD !
        .while TRUE
                .if WORD ptr [edi] == IMAGE_DOS_SIGNATURE
                        mov  esi, edi
                        add  esi, [esi+03Ch]
                        .if  DWORD ptr [esi] == IMAGE_NT_SIGNATURE
                                .break
                        .endif
                .endif
                ExceptCont:
                sub  edi, 010000h
                .if edi < MIN_KERNEL_SEARCH_BASE
                        mov  edi, 0bff70000h
                        .break
                .endif
        .endw
        xchg    eax, edi
        pop     DWORD ptr fs:[0]
        add     esp, 4
        ret     4
; returns address or NULL in the case of an error
GetProcAddr:
        lea     eax, [ebp+offset SehHandler]
        push    eax
        push    DWORD ptr fs:[0]
        lea     eax, [ebp+offset SEH]
        assume  eax:ptr sSEH
        mov     [eax].OrgEsp, esp
        mov     [eax].OrgEbp, ebp
        lea     ebx, [ebp+offset ExceptCont]
        mov     [eax].SaveEip, ebx
        mov     fs:[0], esp
        assume  eax:NOTHING
        ; check PE Signarue
        mov     esi, [esp+0ch]
        cmp     WORD ptr [esi], IMAGE_DOS_SIGNATURE
        JNZ     @@BadExit
        add     esi, [esi+03Ch]
        cmp     DWORD ptr [esi], IMAGE_NT_SIGNATURE
        JNZ     @@BadExit
        ; get the string length of the target Api
        mov     edi, [esp+10h]
        mov     ecx, MAX_API_STRING_LENGTH
        xor     al, al
        repnz   scasb
        mov     ecx, edi
        sub     ecx, [esp+10h]                          ; ECX -> Api string 
lenggth
        ; trace the export table
        mov     edx, [esi+078h]                         ; EDX -> Export tabl
e
        add     edx, [esp+0ch]
        assume  edx:ptr IMAGE_EXPORT_DIRECTORY
        mov     ebx, [edx].AddressOfNames               ; EBX -> AddressOfNa
mes array
pointer
        add     ebx, [esp+0ch]
        xor     eax, eax                                ; eax AddressOfNames
 Inddex
        .repeat
                mov     edi, [ebx]
                add     edi, [esp+0ch]                  ; imagebase
                mov     esi, [esp+10h]                  ; szapi
                push    ecx                             ; save the api strin
g leength
                repz    cmpsb
                .if zero?
                        add  esp, 4
                        .break
                .endif
                pop     ecx
                add     ebx, 4
                inc     eax
        .until eax == [edx].NumberOfNames
        ; did we found sth ?
        .if eax == [edx].NumberOfNames
                jmp @@BadExit
        .endif
        ; find the corresponding Ordinal
        mov     esi, [edx].AddressOfNameOrdinals
        add     esi, [esp+0ch]
        push    edx                             ; save the export table poin
ter
        mov     ebx, 2
        xor     edx, edx
        mul     ebx
        pop     edx
        add     eax, esi
        xor     ecx, ecx
        mov     WORD ptr cx, [eax]              ; ECX -> Api Ordinal
        mov     edi, [edx].AddressOfFunctions   ; get the address of the api

        xor     edx, edx
        mov     ebx, 4
        mov     eax, ecx
        mul     ebx
        add     eax, [esp+0ch]
        add     eax, edi
        mov     eax, [eax]
        add     eax, [esp+0ch]                  ; dwDllBase
        jmp     @@ExitProc
        assume  edx:NOTHING
@@BadExit:
        xor     eax, eax
@@ExitProc:
        pop     DWORD ptr fs:[0]                ; shutdown SEH frame
        add     esp, 4
        ret     8
SehHandler proc C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:
DWORD
        mov     eax, pContext
        assume  eax:ptr CONTEXT
        push    SEH.SaveEip
        pop     [eax].regEip
        push    SEH.OrgEsp
        pop     [eax].regEsp
        push    SEH.OrgEbp
        pop     [eax].regEbp
        mov     eax, ExceptionContinueExecution
        ret
SehHandler endp
Loader_DATAS:
dwOriginEntryPoint      dd 0
szLoadLibrary           db "LoadLibraryA",0
szGetProcAddress        db "GetProcAddress",0
szExitProcess           db "ExitProcess",0
szUser32                db "user32",0
szMessageBox            db "MessageBoxA",0
szMessage               db "- Hello! -",0
_LoadLibrary            dd 0
_ExitProcess            dd 0
_GetProcAddress         dd 0
_MessageBox             dd 0
SEH                     sSEH <0>
dwKernelBase            dd 0
dwUserBase              dd 0
Loader_ASMEND:
_DATA ends
end
// filename: test.cpp
#include <windows.h>
#include <stdio.h>
#define EXENAME         "f:\\super3Cheat.exe"
extern "C" BYTE Loader_ASM,Loader_ASMEND,Loader_DATAS;
DWORD AddSectionToPE(HANDLE hFile,DWORD base,CHAR Name[8],DWORD
Characteristics,LPVOID data,DWORD dwSize)
{
        IMAGE_NT_HEADERS                *pNTHeader;
        IMAGE_SECTION_HEADER    *pSectionHeader1,*pSectionHeader2;
        WORD                                    wNewSize;
        DWORD                                   dwBytesWrite;
        pNTHeader=(IMAGE_NT_HEADERS *)(base+((IMAGE_DOS_HEADER
*)base)->e_lfanew);
        wNewSize=(pNTHeader->FileHeader.
NumberOfSections+1)*sizeof(IMAGE_SECTION_HEADER)\
                +((IMAGE_DOS_HEADER *)base)->e_lfanew+sizeof(IMAGE_FILE_HEAD
ER)\
                +pNTHeader->FileHeader.SizeOfOptionalHeader+4;
        if (wNewSize>pNTHeader->OptionalHeader.SizeOfHeaders)
                return (DWORD)-1;       // not enough space for additional h
eade
        pNTHeader->FileHeader.NumberOfSections++;
        pSectionHeader1=(IMAGE_SECTION_HEADER
*)(base+wNewSize-2*sizeof(IMAGE_SECTION_HEADER));
        pSectionHeader2=(IMAGE_SECTION_HEADER
*)(base+wNewSize-sizeof(IMAGE_SECTION_HEADER));
        strcpy((CHAR *)pSectionHeader2->Name,Name);
        pSectionHeader2->VirtualAddress=pNTHeader->OptionalHeader.SizeOfImag
e;
        pSectionHeader2->Misc.VirtualSize=dwSize;
        pSectionHeader2->SizeOfRawData=(pSectionHeader2->Misc.
VirtualSize/pNTHeader->\
                OptionalHeader.FileAlignment+1)*pNTHeader->OptionalHeader.
FileAlignment;
        pSectionHeader2->PointerToRawData=pSectionHeader1->SizeOfRawData+pSe
cti
onHeader1->PointerToRawData;
        pSectionHeader2->Characteristics=Characteristics;
        pNTHeader->OptionalHeader.SizeOfImage+=(pSectionHeader2->Misc.
VirtualSize/pNTHeader->\
                OptionalHeader.SectionAlignment+1)*pNTHeader->OptionalHeader
.
SectionAlignment;
        SetFilePointer(hFile,0,0,FILE_END);
        WriteFile(hFile,data,pSectionHeader2->SizeOfRawData,&dwBytesWrite,
NULL);
        return pSectionHeader2->VirtualAddress;
}
int main()
{
        HANDLE          hFile;
        HANDLE          hMapping;
        LPVOID          pMapping;
        IMAGE_NT_HEADERS        *pNTHeader;
        LONG            lHeaderOffset;
        DWORD           dwOldEntryPoint;
        hFile=CreateFile(EXENAME,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,\
                NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
        hMapping=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
        pMapping=MapViewOfFile(hMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);

        lHeaderOffset=((IMAGE_DOS_HEADER *)pMapping)->e_lfanew;
        pNTHeader=(IMAGE_NT_HEADERS *)((BYTE *)pMapping+lHeaderOffset);
        if (pNTHeader->Signature!=IMAGE_NT_SIGNATURE){
                printf("not a PE!\n");
                return 101;
        }
        dwOldEntryPoint=pNTHeader->OptionalHeader.
AddressOfEntryPoint+pNTHeader->OptionalHeader.ImageBase;
        *(DWORD *)&Loader_DATAS=dwOldEntryPoint;
        pNTHeader->OptionalHeader.AddressOfEntryPoint=
        AddSectionToPE(hFile,(DWORD)pMapping,".esper",0xE0000020,&Loader_ASM
,
&Loader_ASMEND-&Loader_ASM);
        UnmapViewOfFile(pMapping);
        CloseHandle(hMapping);
        CloseHandle(hFile);
        return 0;
}
  

--
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.236.144]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:208.285毫秒