Désassemblage dynamique

Pour discuter de l'assembleur
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Désassemblage dynamique

Message par Ollivier »

Je poste ce code qui désassemble le code machine en instruction assembleur de manière dynamique.

Code : Tout sélectionner

;{ Données du programme enfant }
DataSection
Data.S "Error.I = 1"
Data.S "If OpenConsole()"
Data.S "If ExamineAssembly(?CodeStart, ?CodeEnd):"
Data.S "If NextInstruction()"
Data.S "BaseAdress.I = InstructionAddress()"
Data.S "PrintN(InstructionString() )"
Data.S "Input()"
Data.S "Error = 0"
Data.S "EndIf"
Data.S "EndIf"
Data.S "CloseConsole()"
Data.S "EndIf"
Data.S "End Error"
Data.S "CodeStart:"
Data.S "CodeEnd:"
Data.S ""
EndDataSection
;}

Global Dim TrustLine.S(31)

#Home = #PB_Compiler_Home

Structure OpString
   TrustFileName.S
   Value.S
   CplProg.I   
   TrustLineQty.I
   CodeOp.I[63]
   CodeQty.I
EndStructure

Procedure.S CplInput(St.S)
   Protected I.I
   Protected Result.S
   Result = UCase(St)
   Result = ReplaceString(Result, ";", Chr(9) )
   ProcedureReturn Result
EndProcedure

Procedure ReadTrust(*C.OpString) ; one time !
   Protected St.S
   With *C
      Repeat
         Read.S St
         If St <> ""
            TrustLine(\TrustLineQty) = St
            \TrustLineQty + 1
         EndIf
      Until St = ""
   EndWith
EndProcedure

Procedure PreStoreTrust(*C.OpString, St.S) ; Etape A
   Protected I.I
   With *C
      \CodeQty = CountString(St, ".") + 1
      For I = 0 To CountString(St, ".")     
         \CodeOp[I] = Val(StringField(St, I + 1, ".") )
      Next I
   EndWith
EndProcedure

Procedure StoreTrust(*C.OpString) ; Etape B
   Protected I.I
   With *C
      CreateFile(0, #Home + \TrustFileName + ".pb")
         For I = 0 To \TrustLineQty - 2
            WriteStringN(0, TrustLine(I) )
         Next I
         For I = 0 To \CodeQty - 1
            WriteStringN(0, "! DB " + Str(\CodeOp[I] ) )
         Next I
         WriteStringN(0, TrustLine(\TrustLineQty - 1) )
      CloseFile(0)
   EndWith
EndProcedure

Procedure CompileTrust(*C.OpString)
   With *C
      WriteProgramStringN(\CplProg, CplInput("SOURCE;" + #Home + \TrustFileName + ".pb") )
      WriteProgramStringN(\CplProg, CplInput("TARGET;" + #Home + \TrustFileName + ".EXE") )
      WriteProgramStringN(\CplProg, "COMPILE")
      ReadProgramString(\CplProg)
   EndWith
EndProcedure

Procedure.I ExecTrust(*C.OpString) ;

   Protected Result.I
   With *C
      Trust = RunProgram(#Home + \TrustFileName + ".EXE", "", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Write | #PB_Program_Hide)
      \Value = ReadProgramString(Trust)
      WriteProgramStringN(Trust, " ")
      While ProgramRunning(Trust)
         Delay(16)
      Wend
      Result = ProgramExitCode(Trust)
      CloseProgram(Trust)
   EndWith
   ProcedureReturn Result.I

EndProcedure

Procedure RecordTrust(*C.OpString) ;
   With *C
      Debug \Value
   EndWith
EndProcedure

Procedure CplOpen(*C.OpString)
   Protected St.S
   With *C
      \CplProg = RunProgram(#PB_Compiler_Home+"\Compilers\pbcompiler", "/STANDBY", "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Write|#PB_Program_Hide)
      If \CplProg
         Repeat
            Delay(15)
            St = ReadProgramString(\CplProg)
         Until St = "READY"
      Else
         MessageRequester("/!\", "Code 3")
      EndIf
   EndWith
EndProcedure

Procedure CplClose(*C.OpString)
   With *C
      WriteProgramStringN(\CplProg, "END")
      While ProgramRunning(\CplProg)
         Delay(100)
      Wend
      If ProgramExitCode(\CplProg) <> 0
         MessageRequester("/!\", "Code 2")
      EndIf
      CloseProgram(\CplProg)
   EndWith
EndProcedure

Procedure.S DisAsm(*C.OpString, St.S)
   Protected Result.S
   With *C
      Delay(500)
      PreStoreTrust(*C, St) ; CodeChaîne >> CodeNum
      StoreTrust(*C) ; CodeNum >> FichPB
      CompileTrust(*C) ; FichPB >> FichEXE
      ExecTrust(*C) ; FichEXE >> CodeOp
;   RecordTrust(Op) ; CodeOp >> Enregistrement
      Result = \Value
   EndWith
   ProcedureReturn Result
EndProcedure

Procedure Main()

   Protected Op.OpString
   Protected St.S
   
   Op\TrustFileName = "Temp"
   ReadTrust(Op)
   
   CplOpen(Op)   
      OpenConsole()
      Repeat         
         PrintN(" ")
         PrintN("Saisissez un code machine. Puis validez avec la touche [Entree].")
         PrintN("Le code doit etre en decimal.")
         PrintN("Le code est ecrit octet apres octet, separe d'un point.")
         PrintN("Exemple: 0.0 (Ici, le code machine se compose de 2 octets chacun etant egal a zero.")
         St = Input()
         If St = ""
            Break
         Else
            Print("Le code machine de " + St + " est : ")
            PrintN(UCase(DisAsm(Op, St) ) )
            Print("Appuyez sur [Entree] pour continuer...")
            Input()
         EndIf
      ForEver
      CloseConsole()
   CplClose(Op)
   
EndProcedure

   Main() 
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Message par Fig »

Ca marche super bien, mais je n'ai pas compris comment :?
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Regarde la procédure DisAsm(). Elle contient plein de commentaires étape par étape. ça te donne une idée de la gymnastique effectuée (utilisation du compilateur, des pipes, de la bibliothèque de désassemblage, etc...).

Ollivier
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

On voit qu'Ollivier code beaucoup! C'est un très beau programme, fait par un programmeur très talentueux.
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Moi je ne suis pas talentueux et je ne mérite rien! Ce sont les auteurs de la bibliothèque OnError qui méritent d'être remerciés depuis 2003 (année de création de la lib) : Siegfried Rings et Sebastian Lackner.

Quelque part, même si techniquement c'est une gymnastique complexe, je n'ai créé qu'une "porte" qui mène à l'une des nombreuses utilisations offertes par la librairie OnError.

Si j'avais dû me coltiner tout le jeux, je n'en serais encore qu'au tiers ou à la moitiée: c'est très complexe. L'EXE résultant fait 100Ko à vide!!

Ollivier
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Je n'ai jamais utilisé cette lib, merci pour l'info. Notre "petit" langage" ne cessera jamais de m'étonner. C'est du bonheur!
Répondre