Code archives/Miscellaneous/BlitzHacker

This code has been declared by its author to be Public Domain code.

Download source code

BlitzHacker by Vertex2004
This little tool show, what can any person hack in your programs. Thx to ShadowTurtle!
You need BlitzUI - http://www.legacygames.co.uk/downloads.php
[img]http://vertex.art-fx.org/blitzhacker.png[/img]
I have done without any exact values to save commercial programs.
; --------------------------------------------------------------------------------------------
Include "../blitzui.bb"
Include "../extras/messagebox.bb"
Include "../extras/opensavedialog.bb"

Graphics 430, 433, 32, 2
SetBuffer BackBuffer()
AppTitle "BlitzHacker"
Initialise()
; --------------------------------------------------------------------------------------------

; --------------------------------------------------------------------------------------------
Type functions_t
   Field offset
   Field name$
End Type

Type types_t
   Field offset
   Field name$
End Type

Type globals_t
   Field offset
   Field name$
End Type

Type arrays_t
   Field offset
   Field name$
End Type

Type labels_t
   Field offset
   Field name$
End Type

Const sizeBlitz3D   = 1048576 ; for Blitz3D-Executables only
Const sizeBlitzPlus = 900000  ; for Blitz3D- and BlitzPlus-Executables, but slower for Blitz3D

Global functions.functions_t, types.types_t, globals.globals_t, arrays.arrays_t, labels.labels_t
Global functionCount, typeCount, globalCount, arrayCount, labelCount, mainOffset = 0
Global fileName$
; --------------------------------------------------------------------------------------------

; --------------------------------------------------------------------------------------------
Global winMain      = Window(-1, -1, 430, 433, "BlitzHacker", "0", 0, 0, 0, 0)

Global cmdLoad      = Button(5, 5, 205, 20, "Load...", "0", 1, 0, 0)
Global cmdSave      = Button(215, 5, 205, 20, "Save...", "0", 1, 0, 0)

Global lblFunctions = Label(5, 30, "Functions:", 0)
Global lblTypes     = Label(5, 110, "Types:", 0)
Global lblGlobals   = Label(5, 190, "Globals:", 0)
Global lblArrays    = Label(5, 270, "Arrays:", 0)
Global lblLabels    = Label(5, 350, "Labels:", 0)

Global lstFunctions = ListBox(5, 45, 415, 60, 20, 20, 10, 0)
Global lstTypes     = ListBox(5, 125, 415, 60, 20, 20, 10, 0)
Global lstGlobals   = ListBox(5, 205, 415, 60, 20, 20, 10, 0)
Global lstArrays    = ListBox(5, 285, 415, 60, 20, 20, 10, 0)
Global lstLabels    = ListBox(5, 365, 415, 60, 20, 20, 10, 0)

SendMessage(cmdSave, "BM_DISABLE")
; --------------------------------------------------------------------------------------------

; --------------------------------------------------------------------------------------------
Repeat
   UpdateGUI()
   
   Select app\Event
      Case EVENT_WINDOW
         Select app\WindowEvent
         End Select
      Case EVENT_MENU
         Select app\MenuEvent
         End Select
      Case EVENT_GADGET
         Select app\GadgetEvent
            Case cmdLoad
               result$ = FileDialog("Open File", "", "exe", False)
               UpdateGUI() : Flip
               hackExe(result$)
            Case cmdSave
               result$ = FileDialog("Save Log", "", "txt", True)
               If result$<>"" And result$<>"Cancel" Then
                  stream = WriteFile(result$)
                  If stream = False Then
                     result$ = MessageBox$("Cannot save file", "Error", 1)
                     UpdateGUI() : Flip
                  Else
                     AppTitle "BlitzHacker :: "+getFileName$(fileName$)+" | in progress..."
                     SendMessage(cmdSave, "BM_DISABLE")
                     SendMessage(cmdLoad, "BM_DISABLE")
                     UpdateGUI() : Flip
                     
                     WriteLine stream, "BlitzHacker :: "+fileName
                     WriteLine stream, "Date:       "+CurrentDate$()
                     WriteLine stream, "Time:       "+CurrentTime$()
                     WriteLine stream, "Mainoffset: "+Hex$(mainOffset)
                     WriteLine stream, ""
                  
                     WriteLine stream, "Functions("+functionCount+"):"
                     For functions = Each functions_t
                        WriteLine stream, Hex$(functions\offset)+" :: "+functions\name$
                     Next : WriteLine stream, ""

                     WriteLine stream, "Types("+typeCount+"):"
                     For types = Each types_t
                        WriteLine stream, Hex$(types\offset)+" :: "+types\name$
                     Next : WriteLine stream, ""

                     WriteLine stream, "Globals("+globalCount+"):"
                     For globals = Each globals_t
                        WriteLine stream, Hex$(globals\offset)+" :: "+globals\name$
                     Next : WriteLine stream, ""
      
                     WriteLine stream, "Arrays("+arrayCount+"):"
                     For arrays = Each arrays_t
                        WriteLine stream, Hex$(arrays\offset)+" :: "+arrays\name$
                     Next : WriteLine stream, ""
      
                     WriteLine stream, "Labels("+labelCount+"):"
                     For labels = Each labels_t
                        WriteLine stream, Hex$(labels\offset)+" :: "+labels\name$
                     Next
      
                     CloseFile stream
                     
                     SendMessage(cmdLoad, "BM_ENABLE")
                     SendMessage(cmdSave, "BM_ENABLE")
                     UpdateGUI() : Flip
                     AppTitle "BlitzHacker :: "+getFileName$(fileName$)+" | ready"
                  EndIf
               EndIf   
         End Select
   End Select
   
   ResetEvents()

   Flip
Until KeyHit( 1 ) Or app\Quit = True

Destroy() : End
; --------------------------------------------------------------------------------------------

; --------------------------------------------------------------------------------------------
Function hackExe(file$)
   Local stream, result$, i, buffer$, byte, offset, name$, del
   
   ; find "__MAIN"
   stream = ReadFile(file$)
   If stream = False Then
      result$ = MessageBox$("Cannot open file", "Error", 1)
      UpdateGUI() : Flip
      Return
   EndIf
   SeekFile stream, sizeBlitzPlus
   While Not Eof(stream)
      If ReadByte(stream) = Asc("_") Then
         For i=1 To 5
            buffer$ = buffer$ + Chr$(ReadByte(stream))
         Next
         If buffer$ = "_MAIN" Then
            mainOffset = FilePos(stream)-5
            Exit
         Else
            buffer$ = ""
         EndIf
      EndIf
   Wend
   If mainOffset > 0 Then
      result$ = MessageBox$("Mainoffset at "+Hex$(mainOffset)+", please wait...", "Found Mainoffset", 1)
      Delete Each functions_t : SendMessage(lstFunctions, "LM_RESET")
      Delete Each types_t     : SendMessage(lstTypes, "LM_RESET")
      Delete Each globals_t   : SendMessage(lstGlobals, "LM_RESET")
      Delete Each arrays_t    : SendMessage(lstArrays, "LM_RESET")
      Delete Each labels_t    : SendMessage(lstLabels, "LM_RESET")
      SendMessage(cmdLoad, "BM_DISABLE")
      SendMessage(cmdSave, "BM_DISABLE")
      UpdateGUI() : Flip
      AppTitle "BlitzHacker :: "+getFileName$(file$)+" | in progress..."
      fileName$ = file$
   Else
      result$ = MessageBox$("The file is not a Blitzexecutable!", "Error", 1)
      CloseFile stream
      Return
   EndIf
   
   ; find functions
   functionCount = 0 : buffer$ = ".."
   While Not Eof(stream)
      buffer$ = Right$(buffer$, 1)+Chr$(ReadByte(stream))
      If buffer$ = "_f" Then
         offset = FilePos(stream)-1
         name$  = ""
         While True
            byte = ReadByte(stream)
            If byte = 0 Then
               Exit
            ElseIf byte>47 And byte<123
               name$ = name$+Chr$(byte)
            Else
               name$ = ""
               Exit
            EndIf
         Wend
         
         If name$ = Lower$(name$) And name$<>"" Then
            del = False
            For functions = Each functions_t
               If functions\name$ = name$ Then del = True
            Next
            If del = False Then
               functions = Last functions_t
               functions = New functions_t
               functions\offset = offset
               functions\name$  = name$
               AddListBoxItem(lstFunctions, 0, name$)
               functionCount = functionCount+1
            EndIf
         EndIf
      EndIf
   Wend : UpdateGUI() : Flip
   
   ; find types
   typeCount = 0 : SeekFile stream, mainOffset+5 : buffer$ = ".."
   While Not Eof(stream)
      buffer$ = Right$(buffer$, 1)+Chr$(ReadByte(stream))
      If buffer$ = "_t" Then
         offset = FilePos(stream)-1
         name$  = ""
         While True
            byte = ReadByte(stream)
            If byte = 0 Then
               Exit
            ElseIf byte>47 And byte<123
               name$ = name$+Chr$(byte)
            Else
               name$ = ""
               Exit
            EndIf
         Wend
         
         If name$ = Lower$(name$) And name$<>"" Then
            del = False
            For types = Each types_t
               If types\name$ = name$ Then del = True
            Next
            If del = False Then
               types = Last types_t
               types = New types_t
               types\offset = offset
               types\name$  = name$
               AddListBoxItem(lstTypes, 0, name$)
               typeCount = typeCount+1
            EndIf
         EndIf
      EndIf
   Wend : UpdateGUI() : Flip
   
   ; find globals
   globalCount = 0 : SeekFile stream, mainOffset+5 : buffer$ = ".."
   While Not Eof(stream)
      buffer$ = Right$(buffer$, 1)+Chr$(ReadByte(stream))
      If buffer$ = "_v" Then
         offset = FilePos(stream)-1
         name$  = ""
         While True
            byte = ReadByte(stream)
            If byte = 0 Then
               Exit
            ElseIf byte>47 And byte<123
               name$ = name$+Chr$(byte)
            Else
               name$ = ""
               Exit
            EndIf
         Wend
         
         If name$ = Lower$(name$) And name$<>"" Then
            del = False
            For globals = Each globals_t
               If globals\name$ = name$ Then del = True
            Next
            If del = False Then
               globals = Last globals_t
               globals = New globals_t
               globals\offset = offset
               globals\name$  = name$
               AddListBoxItem(lstGlobals, 0, name$)
               globalCount = globalCount+1
            EndIf
         EndIf
      EndIf
   Wend : UpdateGUI() : Flip
   
   ; find arrays
   arrayCount = 0 : SeekFile stream, mainOffset+5 : buffer$ = ".."
   While Not Eof(stream)
      buffer$ = Right$(buffer$, 1)+Chr$(ReadByte(stream))
      If buffer$ = "_a" Then
         offset = FilePos(stream)-1
         name$  = ""
         While True
            byte = ReadByte(stream)
            If byte = 0 Then
               Exit
            ElseIf byte>47 And byte<123
               name$ = name$+Chr$(byte)
            Else
               name$ = ""
               Exit
            EndIf
         Wend
         
         If name$ = Lower$(name$) And name$<>"" Then
            del = False
            For arrays = Each arrays_t
               If arrays\name$ = name$ Then del = True
            Next
            If del = False Then
               arrays = Last arrays_t
               arrays = New arrays_t
               arrays\offset = offset
               arrays\name$  = name$
               AddListBoxItem(lstArrays, 0, name$)
               arrayCount = arrayCount+1
            EndIf
         EndIf
      EndIf
   Wend : UpdateGUI() : Flip
   
   ; find labels
   labelCount = 0 : SeekFile stream, mainOffset+5 : buffer$ = "...."
   While Not Eof(stream)
      buffer$ = Mid$(buffer$, 2, 3)+Chr$(ReadByte(stream))

      If buffer$ = "_l_2" Then
         offset = FilePos(stream)-1
         name$  = ""
         While True
            byte = ReadByte(stream)
            If byte = 0 Then
               Exit
            ElseIf byte>47 And byte<123
               name$ = name$+Chr$(byte)
            Else
               name$ = ""
               Exit
            EndIf
         Wend

         If name$ = Lower$(name$) And name$<>"" Then
            del = False
            For labels = Each labels_t
               If labels\name$ = name$ Then del = True
            Next
            If del = False Then
               labels = Last labels_t
               labels = New labels_t
               labels\offset = offset
               labels\name$  = name$
               AddListBoxItem(lstLabels, 0, name$)
               labelCount = labelCount+1
            EndIf
         EndIf
      EndIf
   Wend
   
   CloseFile stream
   SendMessage(cmdLoad, "BM_ENABLE")
   SendMessage(cmdSave, "BM_ENABLE")
   AppTitle "BlitzHacker :: "+getFileName$(file$)+" | ready"
End Function

Function getFileName$(path$)
   Local length, i, find
   
   length = Len(path$)
   For i=1 To length
      If Mid$(path$, i, 1) = "\" Then
         find = i
      EndIf
   Next
   
   Return Right$(path$, length-find)
End Function
; --------------------------------------------------------------------------------------------

Comments

Dragon572004
I notice all extracted type names for my programs have the first letter chopped off. I haven't dug into your code to see what the problem may be.


GW2004
Thats pretty cool!
UPX seems to defeat it though.


Azathoth2004
Does this mean Blitzbasic is an interpreter that appends the code to a stub?


Bot Builder2004
No. I know blitz is compiled. It seems to be reading from an area with the name of the elements, like arrays, functions, etc. I'll bet they are mainly for the debugger, perhaps some other purpose. This doesn't allow anyone to hack your programs or anything like that :-> It doesn't matter if they change it, and if they make it longer/shorter then it'd probably have an error (just a guess). If you are really worried about someone hacking your program, make a Md5 or other routine to check that the program is the same as you created it. You would however have to store the Md5 value in a seperate file(encrypted hopefully along with other data), as otherwise you could never actually compile a program with it because changing the Md5 check in the program would change the actual Md5 :P


Vertex2004
Hi!
Hmmm i have too wondered about this, and have me quest, if Blitz a compiler or a interpreter, but i think too like bot builder that blitz is a compiler and this is only for the debugger(and blitz is to fast for a interpreter).
GW: The Exe must be load unextracted in the memory to execute on windows, so you can hack this exe too.
bot builder: i can for example read the values of Globals etc. i must only find a connection to an offset.
cu olli


Ice92004
If you can change that area of the executable without affecting the way the executable executes, wouldn't a tool that strips unused areas of the executable out of the file be useful?


Bot Builder2004
Yes. Which is one of the things UPX does :D although, it does add a little loading overhead.


Conan2005
Ok... what the hell is this useful for?
I mean, it only gives the names of functions and everything, but not the function...

Whatever!


n8r2k2006
links dead, anyone have BlitzUI?


n8r2k2006
hello?


n8r2k2006
okay I found it not sure if its the same but JFK posted a link in the begginers 3d forum. Any one cares heres the link: www.melog.ch/dl/blitzui_130.zip


bytecode772006
hey, thats pretty cool...a must say :)
i'll try to understand the code and make more of it
let's see what i can do...

edit: is it possible to extract the blitz source code from the exe? that would be revolutionary!


jfk EO-111102006
First of all: it is illegal to modify an Exe that is copyright protected (everything but open source), no matter what reason for.

I really don't like this. "to extract the blitz source code" would not be revolutionary, but theft. Lazy people would try to steal the work from hard working coders.

There is a lot of sourcecode that was kindly provided by many programmers.

Besides, I am pretty sure blitz code cannot be extracted, other than disassembled to ASM with numberic labels etc., because if you consider the speed of EG a simple FOR loop that is running with the speed of say 70% of compiled C++ code, an interpreter (like DB classic) is always several times slower.

So don't edit/patch or back-engineer EXEs, unless you want to be sued.


n8r2k2006
you should be ashamed, I didnt crawl through the net to find that link,(i actually used google to find it) so someone can go and actaully hack someones hardwork.


impersonalis2007
Hi!
Some notices on the algorithm:
1) target piece of an exe file should be cached in buffer (this will increase performance)
2) after (1) recurring block of code may be replaced by a function call; this will reduce the size of the code by 50% and increase its readability
3) there is a weak place in the code: if the name of a variable contains prefix '_f' (e.g. 'my_flag'), it will be treated as a function; the same rule goes for the other prefixes
4) the mentioned offset doesn't work for Blitz+ (afaik)
........
an optimized (though not fixed) version of the algorithm with winGUI may be downloaded here http://rapidshare.com/files/50176416/BHack_zip_.zip.html


ShadowTurtle2007
you have forgot one comment:

"This little tool show, what can any person hack in your programs. ___Thx to ShadowTurtle!___"

please make in your "About" dialog a correcture or remove dialog.


impersonalis2007
http://rapidshare.com/files/51060969/BHack11.zip.html


_332007
If you want to protect your Blitz application from a malicious intrusion with BlitzHack, just UPX it, and change the UPX header so even UPX doesn't recognize it.


puki2007
This thing is pretty lame compared to the 'Biddy' disassembler that will pretty much reverse engineer a Blitz exe back into source.


_332007
I was pretty shocked to find out that the exe actually contains all the labels. I wonder if I could blank them all? That could solve the problem, or maybe replace those labels with sequencial numbers.


nawi2008
it is illegal to modify an Exe that is copyright protected (everything but open source), no matter what reason for.


All works are granted copyright automatically in just about ay country. Secondly, it not illegal to modify programs in most countries, maybe in your fascist state it is.


Code Archives Forum