don't click here

How to write your first hacking program...

Discussion in 'Engineering & Reverse Engineering' started by LOst, Aug 8, 2005.

Thread Status:
Not open for further replies.
  1. LOst

    LOst

    Tech Member
    4,891
    6
    18
    Alright, with no requests, I'm going to show you how to use the C language to write a hacking tool. I will not go into details how to compile it, or how to make a working project in VC++ (but I did). I will not even test it to see if I wrote it correctly (I did it anyway). But I will show you how to access ROM offsets, and how to read and write to it (I didn't get that far, lol). It will be of help.

    What you'll need?

    1)Microsoft Visual C++ 6.0
    2)An UNMODIFIED Sonic 1 ROM.
    3)A knowledge of how hex works. A good knowledge.
    4)A scientific calculator capable of conversion between hex and decimal (Windows calc. works just fine.)
    5)A basic knowledge of C/C++ will definitely help.

    Ready?

    Such a lostgame clone thread lol.

    Select new project and "Win32 console application", and choose "An empty project". Go the the project folder and with a right mouse click on the folder "Source Files", select "Add Files to Folder", and tyoe "main.cpp" in the source file text box and press OK. Now double click on the main.cpp file, and click yes when it asks to create the file.

    Finally, you have a C++ project that will compile into an Win32 console EXE file once you press F5, but don't do that because you have no entry point.

    Use Shift+F7 to compile this main.cpp once in a while to check for errors. Remember that the most common error in C++ is to forget the ; character at the end of each statement.

    Okay, first we need to include some ISO C functions that we will use to access I/O operations. STDIO is what we are going to use for file read/write and output text to the console. We will use CONIO only for a keystroke wait function.

    Okay first add these lines to main.cpp:
    Code (Text):
    1. #include <stdio.h>
    2. #include <conio.h>
    Now we have access to IO libraries and functions of C. Next step is to make it easy for us that use hexeditors. We are going to redirect C++ types into our own names. We all know byte = 1 byte, word = 2 bytes, and dword = 4 bytes. So we just need to redirect C++'s types with the same size into using those names that we can understand better. Add these lines next into main.cpp:
    Code (Text):
    1. typedef unsigned char byte;
    2. typedef unsigned short word;
    3. typedef unsigned long dword;
    We can now use types of bytes and words which is easier when we hack. Next step is to add the entry point function main(), and once you have done that, you can press F5 to run the program. You should have 0 errors and 0 warnings which is a Grade A in C++. ^^
    Add these lines next into main.cpp:
    Code (Text):
    1.  
    2. void main (int argc, byte** argv)
    3. {
    4.     printf ("");
    5.     getch ();
    6. }
    The function call getch() waits for you to press any key in order to exit the program. That's the only function we are going to use from CONIO. The printf() call with a zero string is a bug fix for CONIO in Windows because CONIO is rather old and shouldn't be used.

    Now, the step I am doing here is for us to understand how arguments can be passed to the EXE file. It is important, so that we can use drag'n'drop to drop our Sonic 1 ROM over the EXE icon and make the program find it. This will be confusing at first, but play around a little to see how arguments work:
    Code (Text):
    1. void main (int argc, byte** argv)
    2. {
    3.     printf ("Using %d argument(s):\r\n==================\r\n", argc);
    4.  
    5.     for (int I = 0; I < argc; I++)
    6.     {
    7.  ?printf ("Arg %d: %s\r\n", I, argv [I]);
    8.     }
    9.  
    10.     printf ("");
    11.     getch ();
    12. }
    The code here that I added is not really needed, so don't get caught up into it too much. It outputs text to the console telling what arguments you passed, and how many arguments of course. Printf() has some syntaxes that sould be known:
    %d will be replaced with an integer value. In this case it will be argc, or I.
    %s will be replaced with the string argv [index] points to.
    \r will be replaced with a line feed.
    \n will be replaced with a carrage return.

    So now when you know that, I hope you understand the for-loop statement. If you don't then too bad, because I won't explain it here. The best way to learn it is to search on some javascript example using for-loops because they are identical in function.

    Oh, and the type int which the variavle I and argc are using is a signed dword, so that it can use negative values. Just so you will catch up a little.

    Now to the arguments test. in VC++ 6, you go on the menu "project" and select "settings". On the right side of the dialog, you can see tabs saying "General", "Debug", "C/C++", "Link", and so on. Click on the "Debug" tab. And in the "program arguments" textbox, type the path and file name of the ROM you want to hack. I typed "e:\sega\sonic1.bin". Press OK, and now run the program by pressing F5. You will get an output like this:
    As you can see, and notice is that argument 0 will always be the program name itself. So argument 1 is the ROM name. So by that, you just need to check arg 1 for the path and file name you want to hack. So you can now remove this code from the main() function if you want! You can leave it there to use it for debug output, because I will:
    Code (Text):
    1.     printf ("Using %d argument(s):\r\n==================\r\n", argc);
    2.  
    3.     for (int I = 0; I < argc; I++)
    4.     {
    5.  ?printf ("Arg %d: %s\r\n", I, argv [I]);
    6.     }
    Remove it by using the multi-line comments /* and */ like this:
    Code (Text):
    1. /*  printf ("Using %d argument(s):\r\n==================\r\n", argc);
    2.  
    3.     for (int I = 0; I < argc; I++)
    4.     {
    5.  ?printf ("Arg %d: %s\r\n", I, argv [I]);
    6.     }
    7. */
    Before we start opening the ROM for editing, we need to do am error check to make sure an argument was passed to the program. You do it like this:
    Code (Text):
    1.     if (argc < 2)
    2.     {
    3.  ?printf ("Error:\r\nNo ROM passed as an argument to the program.\r\n");
    4.  ?printf ("");
    5.  ?getch ();
    6.     }

    This is how main.cpp looks so far:
    Code (Text):
    1. #include <stdio.h>
    2. #include <conio.h>
    3.  
    4. typedef unsigned char byte;
    5. typedef unsigned short word;
    6. typedef unsigned long dword;
    7.  
    8. void main (int argc, byte** argv)
    9. {
    10. /*
    11.     printf ("Using %d argument(s):\r\n==================\r\n", argc);
    12.  
    13.     for (int I = 0; I < argc; I++)
    14.     {
    15.  ?printf ("Arg %d: %s\r\n", I, argv [I]);
    16.     }
    17. */
    18.     if (argc < 2)
    19.     {
    20.  ?printf ("Error:\r\nNo ROM passed as an argument to the program.\r\n");
    21.  ?printf ("");
    22.  ?getch ();
    23.     }
    24.  
    25.     printf ("");
    26.     getch ();
    27. }
    I will give you some time to succeed writing it, and if you have 0 errors and 0 warnings, and if it is working like it should, you are ready to write the rest, which I will add later. Now I have to hit shower and bed. I will start up the fun tomorrow! Or whenever I want :P

    See you next time!

    EDIT: Fixed the byte type so that it is unsigned char instead of just char.
     
  2. Lostgame

    Lostgame

    producer/turnablist. homebrew dev. cosplayer. Oldbie
    4,132
    57
    28
    Toronto, ON
    The O.I.C.
    XD

    Thanks, LOst. You saved me the trouble.
     
  3. LOst

    LOst

    Tech Member
    4,891
    6
    18
    But after an hour of just writing this endless thread, I realized I have to make it a sequal of steps. That way it won't get too big. And people will catch up, and be able to ask questions. Great!
     
  4. LOst

    LOst

    Tech Member
    4,891
    6
    18
    Okay, next step is to prepare for data read and write from ROMs. Before you continue, make sure you update your code to say this:
    Code (Text):
    1. typedef unsigned char byte;
    instead of this:
    Code (Text):
    1. typedef char byte;
    Very important. now let's move on shall we?

    Right above the main() function, place this code:
    Code (Text):
    1. inline word swap_word (word value)
    2. {
    3.     return  (value >> 8) | (value << 8);
    4. }
    This will swap the bytes in a word. Let say you want to load a value in the ROM that says 0103. Getting that value into your hacking program will read it backwards like this 0301. So you send the value through the macro C++ function swap_word(), and it will return the word value like it is read in the ROM. I wrote this function myself and I have tested it and it works. inline is the C++ keyword for a function macro. When you call it it will become actual code inserted at compile time, instead of pushing the location onto the stack and call it (which takes time).

    Next we also need a byte swap for double words (dwords)! This is very useful when loading absolute offsets in the Sonic ROM and opening that location for read or write. Here is the code:
    Code (Text):
    1. inline dword swap_dword (dword value)
    2. {
    3.     return  (value >> 24) | ((value & 0x00FF0000) >> 8) |
    4.     &nbsp;((value & 0x0000FF00) << 8) | (value << 24);
    5. }
    Let us assume we want to get the pointer to the Sonic object which we can find at offset D382. In a hexeditor we can see the 4 byte offset as "00 01 2B D8", but when we load it into our hacking program as a double word, it will be byte swapped like this: 0xD82B0100. So we just pass this value through the inline function swap_dword() that I wrote to get it to become right again.

    Reading bytes one and one will not have any swap effects. But reading words and dwords will because the Intel processor we are using for our PC's are little endian CPUs. And the words and dwords are stored backwards so that you can read bytes, words, and dwords from the same address and get the same values.
    So we swap the words with our swap routines when we want to access them in our hacking program, and we swap them back when we want to save them.

    I will add more soon. Here is the main.cpp so far so make sure it works to compile using Shift+F7 and it should give 0 errors and 0 warnings:
    Code (Text):
    1. #include <stdio.h>
    2. #include <conio.h>
    3.  
    4. typedef unsigned char byte;
    5. typedef unsigned short word;
    6. typedef unsigned long dword;
    7.  
    8. inline word swap_word (word value)
    9. {
    10.     return  (value >> 8) | (value << 8);
    11. }
    12.  
    13. inline dword swap_dword (dword value)
    14. {
    15.     return  (value >> 24) | ((value & 0x00FF0000) >> 8) |
    16.     &nbsp;((value & 0x0000FF00) << 8) | (value << 24);
    17. }
    18.  
    19. void main (int argc, byte** argv)
    20. {
    21. /*
    22.     printf ("Using %d argument(s):\r\n==================\r\n", argc);
    23.  
    24.     for (int I = 0; I < argc; I++)
    25.     {
    26.  &nbsp;printf ("Arg %d: %s\r\n", I, argv [I]);
    27.     }
    28. */
    29.     if (argc < 2)
    30.     {
    31.  &nbsp;printf ("Error:\r\nNo ROM passed as an argument to the program.\r\n");
    32.  &nbsp;printf ("");
    33.  &nbsp;getch ();
    34.     }
    35.  
    36.     printf ("");
    37.     getch ();
    38. }
    More to come soon!
     
  5. Lostgame

    Lostgame

    producer/turnablist. homebrew dev. cosplayer. Oldbie
    4,132
    57
    28
    Toronto, ON
    The O.I.C.
    "Soon" eh?

    UpdatePLZ.
     
  6. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    9
    18
    United Kingdom
    YouTuber
    *gasp*

    A battle between LOst and lostgame. Both telling you how to make your own utility. And I'm fucked with both guides XD
     
  7. Lostgame

    Lostgame

    producer/turnablist. homebrew dev. cosplayer. Oldbie
    4,132
    57
    28
    Toronto, ON
    The O.I.C.
    Hey, I didn't update my utlility, either. I'm just interested to what (s)he has to say about it.

    And, not much of a battle anyways, as far as technical knowledge is concerned. Now, as far as good looks and charm are concerned, that's a different story...

    :ph34r:
     
  8. LOst

    LOst

    Tech Member
    4,891
    6
    18
    Since no other requests have been made, I let this topic die.
     
  9. Syren

    Syren

    Member
    4,330
    0
    0
    Teesside, UK
    Reintergration
    Plz update? :thumbsup:
     
  10. Skaarg

    Skaarg

    Member
    3,683
    0
    16
    Just to start people off on something basic, maybe you could explain how to create a a drop down menu that when you click on, it goes to the offset of that level or objects pallete and then another box to edit the values. Just to get people started on something. I've found this to be very interesting though especially since my school doesn't offer a C or C++ class, all we have is VB and they're all retards in there, because I'm On Chapter 5 in the workbook and everybody else is finishing Chapter 2. So L0st be our C teacher. =P
     
  11. Lostgame

    Lostgame

    producer/turnablist. homebrew dev. cosplayer. Oldbie
    4,132
    57
    28
    Toronto, ON
    The O.I.C.
    Plz update, kthxbye.
     
  12. LOst

    LOst

    Tech Member
    4,891
    6
    18
    It's kinda fun how this project turned out to be of great help to me. When I wrote this program, it made it possible for me to take any data and format it to a readable and manageble database.
     
  13. Lostgame

    Lostgame

    producer/turnablist. homebrew dev. cosplayer. Oldbie
    4,132
    57
    28
    Toronto, ON
    The O.I.C.
    LOst has given me permission to update this topic, so expect it in a little while. I have no idea how long, I'm rather busy right now.
     
Thread Status:
Not open for further replies.