刚看到一篇打造自己的MyGetProcAddress没有看见~MyLoadLibrary
这次索性都贴出来好了~
MyGetProcAddress是利用函数名称的Crc32数值搜索出来的
既然MyGetProcAddress好打造了那MyLoadLibrary也很好作大了~
利用用PEB获取地址kernel32.dll基址然后再用GetProcAddress搜出函数指针
UNIT APISE;
{$WARNINGS OFF}
INTERFACE
type
DWORD=LongWord;
PROCEDURE BuildCRC32Table;
FUNCTION CalculateCRC32(VAR Buffer;CONST Size:DWORD) : DWORD;
FUNCTION MyGetProcAddress(Module:Cardinal;ProcessCRC:DWORD) : Pointer;
FUNCTION MyLoadLibraryA:Pointer;
IMPLEMENTATION
CONST
IMAGE_DIRECTORY_ENTRY_EXPORT = 0;
SIZE_OF_80387_REGISTERS = 80;
IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
MAX_API_STRING_LENGTH = 150;
IMAGE_DOS_SIGNATURE = $5A4D;
IMAGE_NT_SIGNATURE = $00004550;
MIN_KERNEL_SEARCH_BASE = $70000000;
TYPE
PImageDosHeader =^TImageDosHeader;
TImageDosHeader = PACKED RECORD
e_magic : WORD;
e_cblp : WORD;
e_cp : WORD;
e_crlc : WORD;
e_cparhdr : WORD;
e_minalloc : WORD;
e_maxalloc : WORD;
e_ss : WORD;
e_sp : WORD;
e_csum : WORD;
e_ip : WORD;
e_cs : WORD;
e_lfarlc : WORD;
e_ovno : WORD;
e_res : ARRAY [0..3] OF WORD;
e_oemid : WORD;
e_oeminfo : WORD;
e_res2 : ARRAY [0..9] OF WORD;
_lfanew : LongInt;
END;
PImageFileHeader =^TImageFileHeader;
TImageFileHeader = PACKED RECORD
Machine : WORD;
NumberOfSections : WORD;
TimeDateStamp : LongWord;
PointerToSymbolTable : LongWord;
NumberOfSymbols : LongWord;
SizeOfOptionalHeader : WORD;
Characteristics : WORD;
END;
PImageDataDirectory =^TImageDataDirectory;
TImageDataDirectory = RECORD
VirtualAddress : LongWord;
Size : LongWord;
END;
PImageOptionalHeader =^TImageOptionalHeader;
TImageOptionalHeader = PACKED RECORD
Magic : WORD;
MajorLinkerVersion : Byte;
MinorLinkerVersion : Byte;
SizeOfCode : LongWord;
SizeOfInitializedData : LongWord;
SizeOfUninitializedData : LongWord;
AddressOfEntryPoint : LongWord;
BaseOfCode : LongWord;
BaseOfData : LongWord;
ImageBase : LongWord;
SectionAlignment : LongWord;
FileAlignment : LongWord;
MajorOperatingSystemVersion : WORD;
MinorOperatingSystemVersion : WORD;
MajorImageVersion : WORD;
MinorImageVersion : WORD;
MajorSubsystemVersion : WORD;
MinorSubsystemVersion : WORD;
Win32VersionValue : LongWord;
SizeOfImage : LongWord;
SizeOfHeaders : LongWord;
CheckSum : LongWord;
Subsystem : WORD;
DllCharacteristics : WORD;
SizeOfStackReserve : LongWord;
SizeOfStackCommit : LongWord;
SizeOfHeapReserve : LongWord;
SizeOfHeapCommit : LongWord;
LoaderFlags : LongWord;
NumberOfRvaAndSizes : LongWord;
DataDirectory : PACKED ARRAY[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] OF TImageDataDirectory;
END;
PImageNtHeaders =^TImageNtHeaders;
TImageNtHeaders = PACKED RECORD
Signature : LongWord;
FileHeader : TImageFileHeader;
OptionalHeader : TImageOptionalHeader;
END;
PImageExportDirectory =^TImageExportDirectory;
TImageExportDirectory = PACKED RECORD
Characteristics : LongWord;
TimeDateStamp : LongWord;
MajorVersion : WORD;
MinorVersion : WORD;
Name : LongWord;
Base : LongWord;
NumberOfFunctions : LongWord;
NumberOfNames : LongWord;
AddressOfFunctions :^PLongWord;
AddressOfNames :^PLongWord;
AddressOfNameOrdinals :^PWord;
END;
VAR
CRC32TAB : ARRAY[0..255] OF DWORD;
PROCEDURE BuildCRC32Table; ASSEMBLER;
ASM
mov ebx, 0EDB88320h
lea edi, crc32tab
xor ecx, ecx
@loc1:
mov eax, ecx
mov edx, 8
@loc2:
test eax, 1
jz @loc3
shr eax, 1
xor eax, ebx
jmp @loc4
@loc3:
shr eax, 1
@loc4:
dec edx
jnz @loc2
stosd
inc ecx
cmp ecx, 256
jb @loc1
END;
FUNCTION CalculateCRC32(VAR Buffer;CONST Size:DWORD) : DWORD; ASSEMBLER;
ASM
push esi
push edi
push ebx
mov edi,edx
mov esi,eax
xor ebx,ebx
mov eax,$ffffffff
mov ecx,edi
shr ecx,2
jecxz @Rest
@Loop:
mov edx,[esi]
mov bl,al
xor bl,dl
shr eax,8
xor eax,dword ptr [CRC32tab+ebx*4]
mov bl,al
xor bl,dh
shr eax,8
xor eax,dword ptr [CRC32tab+ebx*4]
shr edx,16
mov bl,al
xor bl,dl
shr eax,8
xor eax,dword ptr [CRC32tab+ebx*4]
mov bl,al
xor bl,dh
shr eax,8
xor eax,dword ptr [CRC32tab+ebx*4]
add esi,4
loop @Loop
@Rest:
mov ecx,edi
and ecx,3
jecxz @End
@Loop_Rest:
mov bl,al
xor bl,[esi]
shr eax,8
inc esi
xor eax,dword ptr [CRC32tab+ebx*4]
loop @Loop_Rest
@End:
xor eax,$ffffffff
pop ebx
pop edi
pop esi
END;
//------------------------------------------------------------------------------
FUNCTION MyGetProcAddress(Module:Cardinal;ProcessCRC:DWORD) : Pointer;
VAR
ExportName : pChar;
Address : Cardinal;
J : Cardinal;
ImageDosHeader : PImageDosHeader;
ImageNTHeaders : PImageNTHeaders;
ImageExportDirectory : PImageExportDirectory;
BEGIN
ImageDosHeader:=Pointer(Module);
ImageNTHeaders:=Pointer(Module+ImageDosHeader._lfanew);
ImageExportDirectory:=Pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress+Module);
J:=0;
Address:=0;
REPEAT
ExportName:=Pointer(Cardinal(Pointer(Cardinal(ImageExportDirectory.AddressOfNames)+Module+J*4)^)+Module);
IF CalculateCRC32(ExportName^,Length(ExportName))=ProcessCRC THEN
Address:=Cardinal(Pointer(Word(Pointer(J SHL 1+Cardinal(
ImageExportDirectory.AddressOfNameOrdinals)+Module)^) AND
$0000FFFF SHL 2+Cardinal(ImageExportDirectory.AddressOfFunctions)
+Module)^)+Module;
Inc(J);
UNTIL (Address<>0)OR(J=ImageExportDirectory.NumberOfNames);
Result:=Pointer(Address);
END;
FUNCTION MyLoadLibraryA:Pointer;
const
MyLoadLibraryA=$3FC1BD8D;//LoadLibraryA字符串的Crc32数值
asm
mov eax,fs:$30
mov eax,[eax + $0c]
mov esi,[eax + $1c]
lodsd
mov eax,[eax+$08]
mov edx,MyLoadLibraryA
call GetProcAddress
end;
END.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)