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毫秒