wie immer, alle Achtung !!!
Einen Disassembler zu schreiben beinhaltet nicht geraden
geringe kenntnis der Materie.Sind die Opcodes der
x86 Schiene doch gerade nicht
logisch angeordnet(im vergleich zum 680xxx zbsp) .
Was auffällt, eine Disassm-Session einer 2mb großen Exe
dauert manchmal sehr lange.
Deswegen ein paar Vorschläge:
zum Speed:
-Die Listview erst enablen wenn der vorgang fertig ist.
-PeekL benötigt immer mehr Zyklen als wenn man per Pointer
auf nen Speicherbereich direkt zurückgreift.
Zur Übersicht:
-die ganzen Peek's mit absoluten Adressen in der Section machen
das ganze natürlich total unübersichtlich.
besser die Strukturen und damit Pointer des PE-Formates verwenden.
Code: Alles auswählen
IMAGE_DOS_HEADER
IMAGE_DATA_DIRECTORY
IMAGE_OPTIONAL_HEADER
IMAGE_FILE_HEADER
IMAGE_SECTION_HEADER etc.
solche Sachen sind in PB deklariert und auch für X64 verwendbar !
-Die Variablen haben meist zu kleine Namen(3 Zeichen) , etwas länger
wäre besser lesbar(intellisense macht weniger tipparbeit).
wie gesagt, nur Vorschläge.
Was mir persönlich fehlen würde (und das eigentlich nur für
die ExceptionHandler/Trampolin Geschichte),
wäre die Länge eines Opcodes (inkl. Parametern) zu ermitteln.
sowas hier ZumBsp:
Code: Alles auswählen
Procedure getOpCodelength(adress)
*OP.Byte = adress
*OP2.Byte = adress+1
op2=(*OP2\b & $FF )
*OP3.Byte = adress+2
op3=(*OP3\b & $FF )
;Debug Hex(*op\b)
Select ( *OP\b & $FF)
;----------------------
Case $00 ;Eb, Gb
ProcedureReturn 1
; MN$ = "ADD "
Case $83 ;Immediate Gruppe 1 mit 1-Byte-Konstante
;Debug OP2
RM = (OP2 & %00111000) >> 3
;Debug RM
ProcedureReturn 3
; OP = PeekB(Buffer + BZ) & $FF
; OP$ + RSet(Hex(OP), 2, "0") + " "
; BZ + 1
; RM = (OP & %00111000) >> 3 ;reg/opcode für Befehl
; Select RM
; Case 0
; MN$ = "ADD "
; Case 1
; MN$ = "OR "
; Case 2
; MN$ = "ADC "
; Case 3
; MN$ = "SBB "
; Case 4
; MN$ = "AND "
; Case 5
; MN$ = "SUB "
; Case 6
; MN$ = "XOR "
; Case 7
; MN$ = "CMP "
; EndSelect
; Komma = 1
; MSBytes(OP, 2) ;VAR2=2=DWord
; OP = PeekB(Buffer + BZ) & $FF
; OP$ + RSet(Hex(OP), 2, "0") + " "
; H = PeekB(Buffer + BZ) & $FF
; If H < $80 ;Feinheit!
; H$ = "00 00 00 "
; Else
; H$ = "FF FF FF "
; EndIf
; MN$ + H$ + RSet(Hex(H), 2, "0") ;plus der 1-Byte-Wert
; BZ + 1
Case $90
;NOP
ProcedureReturn 1
Case $CC
;INT 3
ProcedureReturn 1
Case x
ProcedureReturn y
EndSelect
EndProcedure
Adresse=?ExampleCode
AdresseEnd=?ExampleCodeEnd
Debug Adresse
For I=Adresse To AdresseEnd -1
Debug Hex(I) + " : " + Hex(PeekL(I) & $FF)
Next I
Debug getOpCodelength(Adresse)
Debug getOpCodelength(Adresse+1)
Debug getOpCodelength(Adresse+2)
If ExamineAssembly(Adresse, AdresseEnd)
While NextInstruction()
;Text$ + RSet(Hex(InstructionAddress()), SizeOf(Integer)*2, "0")
Debug RSet(Hex(InstructionAddress()), SizeOf(Integer)*2, "0") + " "+ InstructionString()
Wend
EndIf
End
ExampleCode:
!NOP
!INT3
!ADD EAX,1
ExampleCodeEnd: