Verfasst: 22.10.2008 19:05
Du musst halt das Executable einlesen und analysieren. Dafür benötigst du Infos über den Formataufbau von Executables. Ist nicht so simpel. Folgender PB-Code ist aus einem meiner Projekte, glaube das war in PB 4.1 oder 4.0.
Der Code ermittelt ein paar der Sachen die oben aufgelistet sind, wie z.b. die Sections. Starte den einfach mal in PB 4.x und gib den Pfad+Dateiname eine .exe ein. Und schau was er dir anzeigt. Ich hab die Manipulation der .exe, die das Programm eigentlich durchführt rausgeworfen.
Der Code ermittelt ein paar der Sachen die oben aufgelistet sind, wie z.b. die Sections. Starte den einfach mal in PB 4.x und gib den Pfad+Dateiname eine .exe ein. Und schau was er dir anzeigt. Ich hab die Manipulation der .exe, die das Programm eigentlich durchführt rausgeworfen.
Code: Alles auswählen
EnableExplicit
#IMAGE_DOS_HEADER = $5A4D
#IMAGE_NT_SIGNATURE = $00004550
#IMAGE_FILE_EXECUTABLE_IMAGE = $2
#IMAGE_FILE_DLL = $2000
#IMAGE_FILE_MACHINE_I386 = $14C
#IMAGE_FILE_MACHINE_I486 = $14D
#IMAGE_FILE_MACHINE_I586 = $14E
#IMAGE_FILE_MACHINE_IA64 = $200
#IMAGE_FILE_MACHINE_AMD64 = $8664
#IMAGE_FILE_MACHINE_ALPHA = $184
#IMAGE_FILE_MACHINE_ARM = $1C0
#IMAGE_FILE_MACHINE_ALPHA64 = $284
#IMAGE_FILE_MACHINE_M68K = $268
#IMAGE_FILE_MACHINE_MIPS16 = $266
#IMAGE_FILE_MACHINE_MIPSFPU = $366
#IMAGE_FILE_MACHINE_MIPSFPU16 = $466
#IMAGE_FILE_MACHINE_POWERPC = $1F0
#IMAGE_FILE_MACHINE_R3000_BE = $160
#IMAGE_FILE_MACHINE_R3000 = $162
#IMAGE_FILE_MACHINE_R4000 = $166
#IMAGE_FILE_MACHINE_R10000 = $168
#IMAGE_FILE_MACHINE_SH3 = $1A2
#IMAGE_FILE_MACHINE_SH4 = $1A6
#IMAGE_FILE_MACHINE_THUMB = $1C2
#IMAGE_NT_OPTIONAL_HDR32_MAGIC = $10B
#IMAGE_NT_OPTIONAL_HDR64_MAGIC = $20B
#IMAGE_ROM_OPTIONAL_HDR_MAGIC = $107
#IMAGE_SCN_MEM_WRITE = $80000000
#IMAGE_SUBSYSTEM_NATIVE = 1
#IMAGE_SUBSYSTEM_WINDOWS_GUI = 2
#IMAGE_SUBSYSTEM_WINDOWS_CUI = 3
#IMAGE_SUBSYSTEM_OS2_CUI = 5
#IMAGE_SUBSYSTEM_POSIX_CUI = 7
#IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9
#IMAGE_SUBSYSTEM_EFI_APPLICATION = 10
#IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11
#IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12
#IMAGE_SUBSYSTEM_EFI_ROM = 13
#IMAGE_SUBSYSTEM_XBOX = 14
#IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16
#IMAGE_ORDINAL_FLAG32 = $80000000
Structure IMAGE_OPTIONAL_HEADER32
MajorLinkerVersion.b
MinorLinkerVersion.b
SizeOfCode.l
SizeOfInitializedData.l
SizeOfUninitializedData.l
AddressOfEntryPoint.l
BaseOfCode.l
BaseOfData.l
ImageBase.l
SectionAlignment.l
FileAlignment.l
MajorOperatingSystemVersion.w
MinorOperatingSystemVersion.w
MajorImageVersion.w
MinorImageVersion.w
MajorSubsystemVersion.w
MinorSubsystemVersion.w
Win32VersionValue.l
SizeOfImage.l
SizeOfHeaders.l
CheckSum.l
Subsystem.w
DllCharacteristics.w
SizeOfStackReserve.l
SizeOfStackCommit.l
SizeOfHeapReserve.l
SizeOfHeapCommit.l
LoaderFlags.l
NumberOfRvaAndSizes.l
EndStructure
Structure IMAGE_OPTIONAL_HEADER64
MajorLinkerVersion.b
MinorLinkerVersion.b
SizeOfCode.l
SizeOfInitializedData.l
SizeOfUninitializedData.l
AddressOfEntryPoint.l
BaseOfCode.l
BaseOfData.l
ImageBase.q
SectionAlignment.l
FileAlignment.l
MajorOperatingSystemVersion.w
MinorOperatingSystemVersion.w
MajorImageVersion.w
MinorImageVersion.w
MajorSubsystemVersion.w
MinorSubsystemVersion.w
Win32VersionValue.l
SizeOfImage.l
SizeOfHeaders.l
CheckSum.l
Subsystem.w
DllCharacteristics.w
SizeOfStackReserve.q
SizeOfStackCommit.q
SizeOfHeapReserve.q
SizeOfHeapCommit.q
LoaderFlags.l
NumberOfRvaAndSizes.l
EndStructure
Structure IMAGE_SECTION_HEADER
Name.s{8}
VirtualSize.l
VirtualAddress.l
SizeOfRawData.l
PointerToRawData.l
PointerToRelocations.l
PointerToLinenumbers.l
NumberOfRelocations.w
NumberOfLinenumbers.w
Characteristics.l
EndStructure
Structure IMAGE_IMPORT_DESCRIPTOR
Characteristics.l
TimeDateStamp.l
ForwarderChain.l
Name1.l
FirstThunk.l
EndStructure
Procedure Exit()
Define.s KeyPressed
PrintN("")
PrintN("Press any key to end program.")
Repeat
Delay(20)
KeyPressed = Inkey()
If KeyPressed <> Chr(0)
End
EndIf
ForEver
End
EndProcedure
Procedure NoPE()
PrintN("")
PrintN("Error: File is no PE (Portable Executable).")
Exit()
EndProcedure
Define.s PEFileName,KeyPressed
Define.l FileLen,OrigFileBuffer,NewFileBuffer,NtHeaderOffset,CPU
Define.l ImageFormat,i,CodeSectionIndex,ImportSectionIndex
Define.l LoadLibraryAImportPointer,ImportRVA,CompCodeSectionBuffer
Define.l CompCodeSectionSize,LoaderCodeBuffer,Position
Define.IMAGE_FILE_HEADER NtFileHeader
Define.IMAGE_OPTIONAL_HEADER32 NtOptionalHeader32
Define.IMAGE_OPTIONAL_HEADER64 NtOptionalHeader64
Define.IMAGE_IMPORT_DESCRIPTOR ImportDescriptor
Dim NtDataDirectory.IMAGE_DATA_DIRECTORY(0)
Dim SectionHeader.IMAGE_SECTION_HEADER(0)
OpenConsole()
ConsoleTitle("Ladon PE-Injector")
PrintN("Ladon PE-Injector v0.01")
PrintN("")
PrintN("Use this tool to inject the Ladon Loader into a Portable Executable file.")
PrintN("Filesize of the target will not increase!")
PrintN("Make sure the Ladon Loader is the first PE manipulator you use on the target.")
PrintN("This is absolute necessary: After compiling the EXE, first inject the Ladon Loader and than any copyprotection, PE protector or EXE compressor.")
PrintN("")
Print("Input filename: ")
PEFileName = Input()
;LoadLibraryA für Test importieren
OpenLibrary(1,"kernel32.dll")
If ReadFile(1,PEFileName) = 0
PrintN("Error: Can't open file.")
Else
;Länge der Datei prüfen
FileLen = Lof(1)
If FileLen < 512
NoPE()
EndIf
;einlesen der Datei
PrintN("")
PrintN("loading file...")
OrigFileBuffer = AllocateMemory(FileLen)
ReadData(1,OrigFileBuffer,FileLen)
CloseFile(1)
PrintN("done")
;analysieren der Datei
PrintN("")
PrintN("analysing file...")
;ist es eine DOS-EXE?
If PeekW(OrigFileBuffer) <> #IMAGE_DOS_HEADER
NoPE()
EndIf
;Offset des NT-Headers auslesen
NtHeaderOffset = PeekL(OrigFileBuffer + 60)
If NtHeaderOffset > FileLen - 4
NoPE()
EndIf
;ist es eine PE-EXE?
If PeekL(OrigFileBuffer + NtHeaderOffset) <> #IMAGE_NT_SIGNATURE
NoPE()
EndIf
;einlesen des NT-File-Headers
CopyMemory(OrigFileBuffer + NtHeaderOffset + 4,NtFileHeader,SizeOf(IMAGE_FILE_HEADER))
;ist Datei eine DLL?
If NtFileHeader\Characteristics & #IMAGE_FILE_DLL = #IMAGE_FILE_DLL
PrintN("")
PrintN("File is a DLL. The Ladon Loader can't be injected into DLL's.")
Exit()
EndIf
;ist die Datei ein stand alone executable?
If NtFileHeader\Characteristics & #IMAGE_FILE_EXECUTABLE_IMAGE <> #IMAGE_FILE_EXECUTABLE_IMAGE
PrintN("")
PrintN("File is not a stand alone executable.")
PrintN("Please link it to a stand alone executable.")
Exit()
EndIf
PrintN("File is a stand alone executable.")
;für welche CPU ist die Datei vorgesehen?
Print("CPU executable was compiled for: ")
Select $0000FFFF & NtFileHeader\Machine
Case #IMAGE_FILE_MACHINE_I386
CPU = 1
PrintN("80386 (386er)")
Case #IMAGE_FILE_MACHINE_I486
CPU = 1
PrintN("80486 (486er)")
Case #IMAGE_FILE_MACHINE_I586
CPU = 1
PrintN("80586 (Pentium)")
Case #IMAGE_FILE_MACHINE_IA64
CPU = 2
PrintN("IA64 (Intel 64bit)")
Case #IMAGE_FILE_MACHINE_AMD64
CPU = 2
PrintN("AMD64 or EM64T (AMD 64bit)")
Case #IMAGE_FILE_MACHINE_ALPHA
PrintN("Alpha AXP")
Case #IMAGE_FILE_MACHINE_ALPHA64
PrintN("Alpha AXP 64bit")
Case #IMAGE_FILE_MACHINE_ARM
PrintN("ARM")
Case #IMAGE_FILE_MACHINE_M68K
PrintN("Motorola 68000 series")
Case #IMAGE_FILE_MACHINE_MIPS16
PrintN("MIPS16")
Case #IMAGE_FILE_MACHINE_MIPSFPU
PrintN("MIPS with FPU")
Case #IMAGE_FILE_MACHINE_MIPSFPU16
PrintN("MIPS16 with FPU")
Case #IMAGE_FILE_MACHINE_POWERPC
PrintN("Power PC")
Case #IMAGE_FILE_MACHINE_R3000_BE
PrintN("R3000 processor, big endian")
Case #IMAGE_FILE_MACHINE_R3000
PrintN("R3000 processor, little endian")
Case #IMAGE_FILE_MACHINE_R4000
PrintN("R4000 processor, little endian")
Case #IMAGE_FILE_MACHINE_R10000
PrintN("R10000 processor, little endian")
Case #IMAGE_FILE_MACHINE_SH3
PrintN("SH3")
Case #IMAGE_FILE_MACHINE_SH4
PrintN("SH4")
Case #IMAGE_FILE_MACHINE_THUMB
PrintN("Thumb")
Default
PrintN("unknown")
EndSelect
;wird die CPU von Ladon unterstützt?
Select CPU
Case 0
PrintN("")
PrintN("The CPU the executable was compiled for is not supported by Ladon!")
Exit()
Case 1
PrintN("Ladon supported 32bit CPU")
Case 2
PrintN("Ladon supported 64bit CPU")
EndSelect
;um was für ein Image handelt es sich?
Select PeekW(OrigFileBuffer + NtHeaderOffset + 4 + SizeOf(IMAGE_FILE_HEADER))
Case #IMAGE_ROM_OPTIONAL_HDR_MAGIC
PrintN("image state: ROM")
PrintN("")
PrintN("Ladon can not run with ROM images!")
Exit()
Case #IMAGE_NT_OPTIONAL_HDR32_MAGIC
PrintN("image state: 32bit")
ImageFormat = 1
Case #IMAGE_NT_OPTIONAL_HDR64_MAGIC
PrintN("image state: 64bit")
ImageFormat = 2
EndSelect
Select ImageFormat
Case 1 ;32bit
;Optinal Header einlesen
CopyMemory(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER), NtOptionalHeader32, SizeOf(IMAGE_OPTIONAL_HEADER32))
;um welches Subsystem handelt es sich?
Print("subsystem: ")
Select NtOptionalHeader32\Subsystem
Case #IMAGE_SUBSYSTEM_NATIVE
PrintN("native")
PrintN("")
PrintN("This executable is a driver.")
PrintN("Ladon dont support drivers.")
Exit()
Case #IMAGE_SUBSYSTEM_WINDOWS_GUI
PrintN("Windows GUI")
Case #IMAGE_SUBSYSTEM_WINDOWS_CUI
PrintN("Windows CUI")
Case #IMAGE_SUBSYSTEM_OS2_CUI
PrintN("OS2 CUI")
PrintN("")
PrintN("This executable is for OS2.")
PrintN("Ladon dont support OS2.")
Exit()
Case #IMAGE_SUBSYSTEM_POSIX_CUI
PrintN("Posix CUI")
PrintN("")
PrintN("This executable is for Posix.")
PrintN("Ladon dont support Posix.")
Exit()
Case #IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
PrintN("Windows CE GUI")
PrintN("")
PrintN("This executable is for Windows CE.")
PrintN("Ladon dont support Windows CE at now.")
Exit()
Case #IMAGE_SUBSYSTEM_EFI_APPLICATION
PrintN("EFI Application")
PrintN("")
PrintN("This executable is a Extensible Firmware Interface.")
PrintN("Ladon dont support EFI.")
Exit()
Case #IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
PrintN("EFI Boot Service Driver")
PrintN("")
PrintN("This executable is a Extensible Firmware Interface.")
PrintN("Ladon dont support EFI.")
Exit()
Case #IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
PrintN("EFI Runtime Driver")
PrintN("")
PrintN("This executable is a Extensible Firmware Interface.")
PrintN("Ladon dont support EFI.")
Exit()
Case #IMAGE_SUBSYSTEM_EFI_ROM
PrintN("EFI ROM")
PrintN("")
PrintN("This executable is a Extensible Firmware Interface.")
PrintN("Ladon dont support EFI.")
Exit()
Case #IMAGE_SUBSYSTEM_XBOX
PrintN("Xbox")
PrintN("")
PrintN("This executable is for Xbox.")
PrintN("Ladon dont support Xbox at now.")
Exit()
Case #IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
PrintN("Windows Boot Application")
PrintN("")
PrintN("This executable is a Boot Application.")
PrintN("Ladon dont support Boot Applications.")
Exit()
Default
PrintN("unknown")
PrintN("")
PrintN("The subsystem of this executable is unknown.")
PrintN("Ladon PE-Injector will not process executables with unknown subsystem.")
Exit()
EndSelect
;Data Directory einlesen
ReDim NtDataDirectory.IMAGE_DATA_DIRECTORY(NtOptionalHeader32\NumberOfRvaAndSizes - 1)
For i = 0 To NtOptionalHeader32\NumberOfRvaAndSizes - 1
NtDataDirectory(i)\VirtualAddress = PeekL(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER) + SizeOf(IMAGE_OPTIONAL_HEADER32) + (i * 8))
NtDataDirectory(i)\Size = PeekL(OrigFileBuffer + NtHeaderOffset + 10 + SizeOf(IMAGE_FILE_HEADER) + SizeOf(IMAGE_OPTIONAL_HEADER32) + (i * 8))
Next
;Section Header einlesen
ReDim SectionHeader.IMAGE_SECTION_HEADER(NtFileHeader\NumberOfSections - 1)
For i = 0 To NtFileHeader\NumberOfSections - 1
CopyMemory(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER) + SizeOf(IMAGE_OPTIONAL_HEADER32) + (8 * NtOptionalHeader32\NumberOfRvaAndSizes) + (i * SizeOf(IMAGE_SECTION_HEADER)), SectionHeader(i), SizeOf(IMAGE_SECTION_HEADER))
Next
Print("sections in executable:")
For i = 0 To NtFileHeader\NumberOfSections - 1
Print(" " + SectionHeader(i)\Name)
Next
PrintN("")
;Codesection identifizieren
CodeSectionIndex = -1
For i = 0 To NtFileHeader\NumberOfSections - 1
If NtOptionalHeader32\AddressOfEntryPoint => SectionHeader(i)\VirtualAddress And NtOptionalHeader32\AddressOfEntryPoint < SectionHeader(i)\VirtualAddress + SectionHeader(i)\SizeOfRawData
CodeSectionIndex = i
Break
EndIf
Next
If CodeSectionIndex = -1
PrintN("")
PrintN("Entry code section not found!")
Exit()
EndIf
PrintN("entry code section: " + SectionHeader(CodeSectionIndex)\Name)
;ist die Codesection schreibbar?
If SectionHeader(CodeSectionIndex)\Characteristics & #IMAGE_SCN_MEM_WRITE <> #IMAGE_SCN_MEM_WRITE
PrintN("The entry code section is not writable.")
PrintN("Note: Entry code section will be writable in new EXE. Do not change that!")
SectionHeader(CodeSectionIndex)\Characteristics | #IMAGE_SCN_MEM_WRITE
Else
PrintN("The entry code section is writable.")
EndIf
;Import Directory nach LoadLibraryA durchsuchen
;Ist das Import Directory vorhanden?
If NtDataDirectory(1)\VirtualAddress = 0
PrintN("")
PrintN("Import directory not found!")
Exit()
EndIf
;Section mit Import Directory ermitteln
ImportSectionIndex = -1
For i = 0 To NtFileHeader\NumberOfSections - 1
If NtDataDirectory(1)\VirtualAddress => SectionHeader(i)\VirtualAddress And NtDataDirectory(1)\VirtualAddress < SectionHeader(i)\VirtualAddress + SectionHeader(i)\SizeOfRawData
ImportSectionIndex = i
Break
EndIf
Next
If ImportSectionIndex = -1
PrintN("")
PrintN("Import directory section not found!")
Exit()
EndIf
PrintN("import directory section: " + SectionHeader(ImportSectionIndex)\Name)
;Import von kernel32.dll suchen
i = 0
Repeat
CopyMemory(OrigFileBuffer + NtDataDirectory(1)\VirtualAddress - SectionHeader(ImportSectionIndex)\VirtualAddress + SectionHeader(ImportSectionIndex)\PointerToRawData + i, ImportDescriptor, SizeOf(IMAGE_IMPORT_DESCRIPTOR))
i + SizeOf(IMAGE_IMPORT_DESCRIPTOR)
If ImportDescriptor\Characteristics = 0 And ImportDescriptor\FirstThunk = 0
PrintN("")
PrintN("Import of kernel32.dll not found!")
Exit()
EndIf
If LCase(PeekS(OrigFileBuffer + ImportDescriptor\Name1 - SectionHeader(ImportSectionIndex)\VirtualAddress + SectionHeader(ImportSectionIndex)\PointerToRawData)) = "kernel32.dll"
;nach LibraryLoadA suchen
i = 0
Repeat
ImportRVA = PeekL(OrigFileBuffer + ImportDescriptor\FirstThunk - SectionHeader(ImportSectionIndex)\VirtualAddress + SectionHeader(ImportSectionIndex)\PointerToRawData + i)
If ImportRVA = 0
PrintN("")
PrintN("Import of LoadLibraryA not found!")
PrintN("Ladon Loader needs the LoadLibraryA API function.")
PrintN("Please import it and recompile your executable.")
Exit()
EndIf
If ImportRVA & #IMAGE_ORDINAL_FLAG32 <> #IMAGE_ORDINAL_FLAG32
If LCase(PeekS(OrigFileBuffer + ImportRVA - SectionHeader(ImportSectionIndex)\VirtualAddress + SectionHeader(ImportSectionIndex)\PointerToRawData + 2)) = "loadlibrarya"
PrintN("LoadLibraryA import found.")
LoadLibraryAImportPointer = NtOptionalHeader32\ImageBase + ImportDescriptor\FirstThunk + i
Break
EndIf
EndIf
i + 4
ForEver
Break
EndIf
ForEver
PrintN("done")
;Rest rausgeworfen, da nichts zur Sache tut ;-)
EndSelect
EndIf
PrintN("")
PrintN("Press any key to end program.")
Repeat
Delay(20)
KeyPressed = Inkey()
If KeyPressed <> Chr(0)
End
EndIf
ForEver