ASM: hardcoded IsDebuggerPresent()

Fragen zu allen anderen Programmiersprachen.
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: ASM: hardcoded IsDebuggerPresent()

Beitrag von freak »

Fluid Byte hat geschrieben:Zwei Fragen:

1.) Wie bekomme ich die Adresse des TIB ohne das FS-Register?
2.) Der ASM-Code ist so nicht 64Bit kompatibel. Korrekt?
zu 1.) Dazu ist mir kein anderer Weg bekannt.
zu 2.) Korrekt. Unter x64 läuft das über das GS-Register, und alle Offsets müssen natürlich angepasst werden, aber generell geht das da auch irgendwie.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: ASM: hardcoded IsDebuggerPresent()

Beitrag von Thorium »

Fluid Byte hat geschrieben:Klingt sehr interessant. Auch wenn ich natürlich Kosten/Nutzen abwäge und sowas für die meisten Projekte nicht in Frage kommt
hätte ich Lust mich damit mit mal näher zu befassen. Gibt es da entsprechende Tutorials oder eine Art Crashkurs um das Ganze mal
besser zu veranschaulichen?
Ich kenne keine hab mich aber auch nie intensiv damit beschäftigt.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: ASM: hardcoded IsDebuggerPresent()

Beitrag von freak »

Fluid Byte hat geschrieben:Klingt sehr interessant. Auch wenn ich natürlich Kosten/Nutzen abwäge und sowas für die meisten Projekte nicht in Frage kommt
hätte ich Lust mich damit mit mal näher zu befassen. Gibt es da entsprechende Tutorials oder eine Art Crashkurs um das Ganze mal
besser zu veranschaulichen?
Da steckt nicht besonders viel dahinter: Du musst dir nur überlegen, wie dein Bytecode aussehen soll (Instruktionen und ihre Parameter) und dann besteht der Interpreter für die Virtuelle Maschine einfach daraus den Bytecode zu lesen und die entsprechenden Instruktionen auszuführen.

Kleines Beispiel:

Code: Alles auswählen

Enumeration
  #ILiteral ; argument: 1-byte literal  
  
  #IPush    ; no arguments
  #IPop  
  #IAdd
  #ISub
  #IMul
  #IDiv
EndEnumeration

Procedure Interpreter(*Code.BYTE, *CodeEnd)
  Protected Dim Stack(50)
  Protected Index = 0
  Protected Accumulator = 0  
  
  While *Code < *CodeEnd
    Select *Code\b
    
      Case #ILiteral
        Accumulator = PeekB(*Code+1)
        *Code + 2
      
      Case #IPush
        If Index = 50
          Debug "Stack overflow"
          Break
        EndIf
        
        Index + 1
        Stack(Index) = Accumulator      
        *Code + 1
        
      Case #IPop
        If Index = 0
          Debug "Stack underflow"
          Break
        EndIf      
      
        Accumulator = Stack(Index)
        Index - 1              
        *Code + 1        
      
      Case #IAdd
        Accumulator = Stack(Index) + Accumulator
        Index - 1
        *Code + 1

      Case #ISub
        Accumulator = Stack(Index) - Accumulator
        Index - 1
        *Code + 1
        
      Case #IMul
        Accumulator = Stack(Index) * Accumulator
        Index - 1
        *Code + 1
        
      Case #IDiv
        Accumulator = Stack(Index) / Accumulator
        Index - 1
        *Code + 1        
    
      Default
        Debug "Invalid Instruction"
        Break
    
    EndSelect
  Wend
  
  ProcedureReturn Accumulator
EndProcedure



Debug Interpreter(?Code1, ?CodeEnd1)
Debug Interpreter(?Code2, ?CodeEnd2)



DataSection
  
  ; Code: (((5 * 7) + (10 - 3)) * 2) = 84
  ;
  Code1:
    Data.b #ILiteral, 5
    Data.b #IPush
    Data.b #ILiteral, 7
    Data.b #IMul
    Data.b #IPush
    Data.b #ILiteral, 10
    Data.b #IPush
    Data.b #ILiteral, 3
    Data.b #ISub
    Data.b #IAdd
    Data.b #IPush
    Data.b #ILiteral, 2
    Data.b #IMul
  CodeEnd1:

  ; Code: 2^5 = 32
  Code2:
    Data.b #ILiteral, 2
    Data.b #IPush
    Data.b #ILiteral, 2
    Data.b #IMul
    Data.b #IPush
    Data.b #ILiteral, 2
    Data.b #IMul
    Data.b #IPush
    Data.b #ILiteral, 2
    Data.b #IMul
    Data.b #IPush
    Data.b #ILiteral, 2
    Data.b #IMul
  CodeEnd2:

EndDataSection
Der ByteCode besteht aus 1-byte für die Instruktion, und noch ein weiteres Parameter für #ILiteral, alle anderen Instruktionen haben keine Parameter in ByteCode. Damit kann der Interpreter einfach ein Select auf dem aktuellen code-byte machen um die aktuelle Instruktion zu ermitteln. Die Architektur der mini-VM ist eine Akkumulator-Maschine, das heißt ein Parameter für eine Instruktion wie #IAdd ist immer das Akkumulator-Register und da landet auch das Ergebnis. Weitere Parameter kommen von dem Stack. Man kann hier jede Architektur nachbauen die man will, ich habe diese verwendet weil sie einen sehr minimalen ByteCode braucht und schnell umzusetzen ist.

Das Beispiel macht natürlich noch nicht besonders viel, aber wenn man noch ein paar mehr Instruktionen einbaut wie zum Beispiel Sprünge und bedingte Sprünge dann kann man schnell kleine Funktionen in dem ByteCode schreiben. Vom Kern her ist das eigentlich echt keine große Sache, es kommt halt drauf an wie weit man die Sache treiben will. Wenn man das Ganze komfortabel nutzen will braucht man schon einen Assembler/Disassember dazu, wenn nicht sogar gleich einen Compiler der den ByteCode erzeugt.
Benutzeravatar
Rings
Beiträge: 977
Registriert: 29.08.2004 08:48

Re: ASM: hardcoded IsDebuggerPresent()

Beitrag von Rings »

nur zur vollständigkeit,
der code für x86 (inline asm einschalten):

Code: Alles auswählen

Procedure  IsDebuggerPresent()
  v=0
  !MOV eax, [fs:$18];
  !MOV eax, [eax+$30];
  !MOVZX eax, byte [eax+2];
  MOV v,eax
  ProcedureReturn v
EndProcedure;
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Re: ASM: hardcoded IsDebuggerPresent()

Beitrag von Blackskyliner »

Hey, freak!
:)

Würdest du das nochmal in Tipps und Tricks posten, damit das nicht in den Weiten der normalen Thread unter geht?
Denn es ist einfach einfach und "very neat" :)
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Re: ASM: hardcoded IsDebuggerPresent()

Beitrag von Fluid Byte »

freak hat geschrieben:Da steckt nicht besonders viel dahinter: Du musst dir nur überlegen, wie dein Bytecode aussehen soll (Instruktionen und ihre Parameter) und dann besteht der Interpreter für die Virtuelle Maschine einfach daraus den Bytecode zu lesen und die entsprechenden Instruktionen auszuführen
Mittels deiner Erläuterungen und dem anschaulichen Demo-Quelltext habe selbst ich das Grundprinzip jetzt verstanden. <)

Nun werde ich das Beispiel modifizieren und kontinuierlich erweitern bis ich das Gefühl habe es in einem schützenswerten
Projekt einzusetzen. Vielen Dank also fürs Beispiel und die hilfreichen Infos.

@Rings:
Exzellent. Funktioniert einwandfrei.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Antworten