Page 1 of 3 123 LastLast
Results 1 to 15 of 32
  1. #1
    Toymaker's Avatar
    Join Date
    Feb 2008
    Gender
    male
    Location
    Hannah, Montana
    Posts
    659
    Reputation
    14
    Thanks
    193
    My Mood
    Amused

    Daily Dose of Assembly

    In this thread I will administer a dose of assembly education each day. This is not a game hacking, or assembly programming, tutorial - it is however practical concepts you can apply...

    DaY 1:

    Introduction:

    In the windows platform, there are modules naturally in active process i.e. kernel32.dll in which with out, your software could not exit properly (the API known as ExitProcess). Your CPU assigns a new memory space per request, on application load, but still allows accessibility to such functions.

    You can not only call them in your programs, such as exit(0); in cplusplus or invoke exitprocess,0 in mASM but, you can at any point in time make use of them in your hacks, or debugging session.

    Practical Uses:

    • Your own hot keys in your hacks
    • Your own exception/error handling
    • Defeating game's own limitations
    • Simulating Key Syncs


    HowTo: Manipulate ExitProcess:

    I have created a quick example program in cplusplus (as it looks the cleanest in disassembly) in where I use exit(0); (which calls Kernel32.ExitProcess). You'll notice in both programmatic examples i've given, there is one parameter to it, and it's 0. Any way, it looks like this:

    Code:
    004013C6  |. C70424 00000000         MOV DWORD PTR SS:[ESP],0                         ; |
    004013CD  |. E8 8EF20000             CALL <JMP.&msvcrt.exit>                          ; exit
    If you try using a CALL EXITPROCESS yourself, you'll notice the address that commonly represents that <JMP.&msvcrt.exit> is 7C81CDEA but may vary. Any way, it is basically all the same. You establish the one parameter and then call the ExitProcess function, in which it passes too. Therefore, you can add...

    Code:
    mov esp,0
    call ExitProcess
    ...to your hacks and force a termination of execution. You could also try a CMP to detect last key pressed, etc. If you are interested in how to use the ESCAPE key as a hotkey, you can look up which parameter / value represents the ESC_Key and pass it to the GetKeySync function:

    Code:
    004013BA  |> C70424 1B000000         /MOV DWORD PTR SS:[ESP],1B                             ; |
    004013C1  |. E8 0AF50000             |CALL <JMP.&USER32.GetKeyState>                        ; GetKeyState
    Code:
    mov esp,1b
    call GetKeySync
    ...although it's actually in user32.dll, another example pre-process module. If you wonder why [ESP] is used, its because it handles the last information for going to and returning from a CALL. It's part of the stack / unique memory space I mentioned, in a sense. That concludes the daily dose of assembly for June 03 2009. Tomorrow will come another, but some one should reply so I don't have to double post and we can keep this thread alive, lawl.
    Last edited by Toymaker; 06-04-2009 at 04:28 PM.

  2. The Following 3 Users Say Thank You to Toymaker For This Useful Post:

    blueduece2 (06-03-2009),hbk (07-08-2009),PlSlYlClHlO (06-03-2009)

  3. #2
    Toymaker's Avatar
    Join Date
    Feb 2008
    Gender
    male
    Location
    Hannah, Montana
    Posts
    659
    Reputation
    14
    Thanks
    193
    My Mood
    Amused
    DaY 2:

    Introduction:

    There are certain cases in which you do not have enough room in the actual function to make much modifcation. If you encounter: 40400D0 | EB08 you obviouslly don't room to change it to some 5 byte CALL to some function. In this Daily Dose of Assembly, i'll explain JMP vs CALL and show you how to use CAVES to avoid using larger amounts of in-Routine memory.

    The first and foremost important concept is a JMP can vary in operand size, while a CALL can not. If you are making a LOCAL jump, and mind you that literally means local to the area, your jump will only consist of 2 bytes. ## ## the first two numbers will represent the type of JMP you're using...

    Code:
    EB = JMP
    74 = JE
    75 = JNE
    E9 ## ## ## ## = If Far Jump
    ...and the second two the amount of bytes away the target offset is. In a CALL situation. It will take up five bytes of memory. E8 ## ## ## ## ## like a Far Jump. The four bytes of ## are basically the target address inversed and tagged.

    The thing that's similar about CALL and JMP is they bump 'move' the current execution to the target address. They both are technically loading the new address into EPI but, only CALL loads the return address, into [ESP] and then subtracts ESP by 4.

    Practical Uses:

    • Making greater modifications than space limitations allow
    • Keeping better track of information to balance


    HowTo: Caves:

    You can use a dissasembler or a debugger to find points of un used, extra assigned, memory that is not temporary. You can simply scroll down to the bottom, in this example with notepad I have

    Code:
    7C97DDE2   0000             ADD BYTE PTR DS:[EAX],AL
    7C97DDE4   0000             ADD BYTE PTR DS:[EAX],AL
    7C97DDE6   0000             ADD BYTE PTR DS:[EAX],AL
    ...for example. I can find some random point in memory and tamper with it to demostrate these ends, without
    causing errors as so

    I look at

    Code:
    7C9012A4   897A 04          MOV DWORD PTR DS:[EDX+4],EDI
    7C9012A7   0BFF             OR EDI,EDI
    There is not enough space to make a 5 byte long jump to our caves but it's okay because we can restore
    memory at it. I'll write it

    Code:
    7C9012A4   E9 39CB0700      JMP ntdll.7C97DDE2
    ...
    7C9012A9   74 22            JE SHORT ntdll.7C9012CD
    I completely ruined the original first two offsets but i can handle it by writing

    Code:
    7C97DDE2   897A 04          MOV DWORD PTR DS:[EDX+4],EDI
    7C97DDE5   09FF             OR EDI,EDI
    7C97DDE7  ^E9 BD34F8FF      JMP ntdll.7C9012A9
    ...to my caves and now every thing is the same, and functions as so, but I added space
    to active memory for my modifying. That concludes DaY 2

  4. #3
    InHuman's Avatar
    Join Date
    Feb 2009
    Gender
    male
    Location
    somewhere with alot of girls
    Posts
    10,684
    Reputation
    655
    Thanks
    1,812
    My Mood
    Stressed
    toymaker i guess i am not getting in..huh?

  5. #4
    Toymaker's Avatar
    Join Date
    Feb 2008
    Gender
    male
    Location
    Hannah, Montana
    Posts
    659
    Reputation
    14
    Thanks
    193
    My Mood
    Amused
    I actually have developed this thread for myself as a hobby when i'm taking breaks between codes. I assume you are referring to being invited to one of two social groups for the new releases on the way. Truth be told, I was going to send you an invite when I sat down and decided who all else to add. I'll send it now, but don't hijack my threads with off topic pish posh any more.

    DaY 3:

    Introduction:

    In this day of the Daily Dose of Assembly by Toymaker, we'll be discussing the fundamentals behind functions and even some obsufcation.

    Notice: I use some c++ examples for the programs i'm 'reversing' in the lessons, beings it's most commonly seen and in a simple form.

    Practiality:

    • Hide your coding from hackers
    • Better understand and use calls


    HowTo: Pass Arguments | Obsfucate:

    You will notice two primary types of functions called in assembly. One set, are in-application functions that were programmed by the user. They are usually called, without notifcation, as their pointer value.

    Code:
    call 4040D00
    ...may be a call to the 'check password' function after you enter a password. Or even to print a string assigned by the application. I'll compare two examples:

    Code:
    004013BA  |. C74424 04 00004400     MOV DWORD PTR SS:[ESP+4],Untitled.00440000        ;  ASCII "Enter Password
    "
    004013C2  |. C70424 C0334400        MOV DWORD PTR SS:[ESP],Untitled.004433C0
    ...versus...

    Code:
    004013E1  |. C70424 10004400        MOV DWORD PTR SS:[ESP],Untitled.00440010          ; |ASCII "pause"
    004013E8  |. E8 93F20000            CALL <JMP.&msvcrt.system>                         ; system
    ...you see one function (004433C0) is the applications own printing function...while below it, <JMP.&msvcrt.system> is clearing making a call to your system. In C++ this would be:

    Code:
    system("pause");
    ...you notice how the assembly sets up "pause" as a parameter, in [ESP], to be passed, via calling, to the system()? In the above example it does the same BUT you notice it moves into both [ESP] and [ESP+4], it's because the "new line" function/command, \n in c++, also counts as a parameter.

    In conclusion, i'll show you a basic example of assembly obsfucation. The normal c++ code for the above was:

    Code:
    cout<<"Enter Passwordn";
    system("pause");
    ...so now what I will be doing is

    Code:
    #define say cout<<
    char* urPrompt = "enter passwordn";
    say urPrompt;
    ...this is the new form, better hidden, in disassembly

    Code:
    004013BF  |. 894424 04                  MOV DWORD PTR SS:[ESP+4],EAX
    004013C3  |. C70424 C0334400            MOV DWORD PTR SS:[ESP],Untitled.004433C0
    004013CA  |. E8 99AC0300                CALL Untitled.0043C068
    ...You notice there's no ;text hint telling you the message now? The pointer
    is hidden behind a register, as well. You can use this simple method to hide your
    code from reversers. ALTHOUGH AFTER the program executes once, the information will
    still be loaded and findable for you at 4433C0.
    Last edited by Toymaker; 06-06-2009 at 11:20 AM.

  6. #5
    Jakor's Avatar
    Join Date
    Feb 2008
    Posts
    48
    Reputation
    10
    Thanks
    0
    Day 1
    Quote Originally Posted by Toymaker View Post
    If you try using a CALL EXITPROCESS yourself, you'll notice the address that commonly represents that <JMP.&msvcrt.exit> is 7C81CDEA but may vary. Any way, it is basically all the same. You establish the one parameter and then call the ExitProcess function, in which it passes too. Therefore, you can add...

    Code:
    mov esp,0
    call ExitProcess
    I have to interject...
    The address to Kernel32.ExitProcess will *NOT* jump around from windows version to windows version (kernel32 is always loaded in the same place in memory everytime for every process according to windows version). msvcrt's library wrapper function will move around. However the code section shows a call to Kernel32.ExitProcess not MSVCRT.exit. Also this would cause an error. mov esp, 0 sets the stack pointer to 00000000 not the data at esp to 0 correct code would look like this:
    Code:
    mov dword ptr [esp],0
    call ExitProcess ;or JMP.&msvcrt.exit
    Quote Originally Posted by Toymaker View Post
    Code:
    mov esp,1b
    call GetKeySync
    See code section above for same mistake... (should be mov dword ptr [esp],1b)

    However, if you are writing code in assembly / debugger take note of the two lines below:

    Code:
    C70424 1B00000>MOV DWORD PTR SS:[ESP],1B   ;6bytes (1B or 00 doesn't matter)
    6A 1B          PUSH 1B   ;2bytes (1B or 00 doesn't matter)
    which one do you think is more efficient?

    Also you need to take care of the stack. While I figured not taking care of it for exitprocess is ok as everything gets deallocated (still not good programming practices), putting a check for keystate in a game loop or watever will seriously screw with the stack.

    Code:
    function proc arg:DWORD
    ret 4
    function endp
    start:
    push 00
    call function
    mov dword ptr [esp], 0
    call function
    ret
    walking through this from start:
    push 00 (performs this: mov dword [esp],00000000, sub esp, 4)
    call function (performs this: mov dword [esp], addr "mov dword ptr [esp], 0", sub esp, 4)
    ret 4 (performs this: add esp 4 then (almost) pop eip)
    mov dword ptr [esp], 0 (performs this: mov dword ptr [esp], 0)
    call function (performs this: mov dword [esp], addr "ret", sub esp, 4)
    ret 4 (performs this: add esp 4 then (almost) pop eip)
    ret (would exit the process un-gracefully)

    If you were to put this in an infinite loop you would see esp do this:
    assuming esp == 00

    @@:
    push 00 ;esp == -4d
    call function ;esp == -8d
    ret 4 ;esp == 00
    mov dword ptr [esp], 0 ;esp == 0
    call function ;esp == -4d
    ret 4 ;esp == 4d
    jmp @B ;next time esp == 8d then 12d then 16d ect....
    ret


    I also have to add that since I am not a c programmer, I don't use cdecl calling convention much (wsprintf being the exception so far). While your disassembly shows the mov dword ptr [esp], that is because it won't have to clean up the stack after the call. Some c libraries work this way, most do not.
    Last edited by Jakor; 06-05-2009 at 07:48 PM.

  7. #6
    Jakor's Avatar
    Join Date
    Feb 2008
    Posts
    48
    Reputation
    10
    Thanks
    0
    DAY 2
    Quote Originally Posted by Toymaker View Post
    Code:
    7C97DDE2   897A 04          MOV DWORD PTR DS:[EDX+4],EDI
    7C97DDE5   09FF             OR EDI,EDI
    7C97DDE7  ^E9 BD34F8FF      JMP ntdll.7C9012A9
    While your example is decent, I would stress that making code caves in the application's module is imperative. I would not suggest making code caves especially in ntdll unless you really know what you are doing.

    At some point you might want to explain dll's and how they save you from needing to use code caves.

  8. #7
    Toymaker's Avatar
    Join Date
    Feb 2008
    Gender
    male
    Location
    Hannah, Montana
    Posts
    659
    Reputation
    14
    Thanks
    193
    My Mood
    Amused
    I can only say 'you are correct' and, 'I know.' I just didn't care to get too detailed or directly correct, in my basic tutorial series. I will continue it, and you can always continue adding to it.
    Last edited by Toymaker; 06-05-2009 at 10:59 PM.

  9. #8
    radnomguywfq3's Avatar
    Join Date
    Jan 2007
    Gender
    male
    Location
    J:\E\T\A\M\A\Y.exe
    Posts
    8,858
    Reputation
    381
    Thanks
    1,823
    My Mood
    Sad
    Quote Originally Posted by Jakor View Post
    DAY 2


    While your example is decent, I would stress that making code caves in the application's module is imperative. I would not suggest making code caves especially in ntdll unless you really know what you are doing.

    At some point you might want to explain dll's and how they save you from needing to use code caves.
    While you are correct, there is tons of excess space in the PE Header, and as long as your careful not to overflow that memory region it's safe. Although, generally you can just load your own library into the target's address space containing the code you wish to execute opposed to writing a code-cave. Seeing as this is an assembly tutorial that would be irrelevant though. Even if you can only push a couple bytes in(chances of this are really low, as there is, like I said, tons of excess space) you can always call APIs to reallocate more memory.
    Last edited by radnomguywfq3; 06-05-2009 at 11:10 PM.

  10. #9
    Jakor's Avatar
    Join Date
    Feb 2008
    Posts
    48
    Reputation
    10
    Thanks
    0
    I will assume we are now talking using code caves to create permanent changes to an application (no need for a dll/loader makes it easy to use).
    Quote Originally Posted by Jetamay View Post
    While you are correct, there is tons of excess space in the PE Header
    The PE Header contains a few deprecated pieces, but overall is based off arrays with pointers. Finding space in here is not a good idea (unless you are removing the dos stub which isn't always a good idea either). You never know what data will be looked at and needs to still be zero. This is why writing to the .code section (which shouldn't need to be read under normal circumstances) is the "right" way (without adding sections).

    Quote Originally Posted by Jetamay View Post
    and as long as your careful not to overflow that memory region it's safe.
    It's easier to add a section than do all the checks to make sure you are not overstepping the bounds in a PE header.

    Quote Originally Posted by Jetamay View Post
    Although, generally you can just load your own library into the target's address space containing the code you wish to execute opposed to writing a code-cave.
    That's what I said he should do a tutorial on at some point.

    Quote Originally Posted by Jetamay View Post
    Seeing as this is an assembly tutorial that would be irrelevant though.
    I don't see how it would be irrelevant. I do it all the time and only use "assembly".

    Quote Originally Posted by Jetamay View Post
    Even if you can only push a couple bytes in(chances of this are really low, as there is, like I said, tons of excess space) you can always call APIs to reallocate more memory.
    this defeats the purpose, unless you are using an external exe to allocate the memory. But then why not make it easy on your self and write a loader (less updating for one thing). A code cave to a VirtualAlloc would still need to copy the code in to execute at some point.

    Code:
    blah
    blah
    jmp codecave
    leftoff:
    blah
    blah
    ..
    codecave:
    overwritten blah
    virtualalloc,NULL,commit/reserve/page read-write-exe
    push eax
    copymem from????????, to-eax,lengthof from?????????
    pop eax
    call eax
    jmp leftoff
    this extra code is useless unless you are adding in a larger amount of code and want to write all the filemapping for a bin(non-pe) module file into an allocated memory area and call that.... however for something that big, again... why not a dll...

  11. #10
    Toymaker's Avatar
    Join Date
    Feb 2008
    Gender
    male
    Location
    Hannah, Montana
    Posts
    659
    Reputation
    14
    Thanks
    193
    My Mood
    Amused
    I'm glad this topic is active and respect you both. I think there is to much unnececary detail, though, considering my goal is to explain unique concepts in a basic manner, thus inspiring users to learn and make it more proficient on their own. I will cover both loading, and even creating, your own memory spaces later. I also, for exampl in this lesson, welcome further discussion on these topics.

    DaY 4:

    Introduction:

    In today's article, I will teach you how to defeat Dynamic Memory Allocation (ever changing addresses) and even how to see it or use it. I again use some cplusplus examples for simplicity. This will be a two part Daily Dose.

    Practicality:

    • Most hacks today require this.
    • You can manipulate it for better hacks, even.



    Part I. HowTo: Defeat DMA

    If you are a hacking a game, meaning virtually any of them, you'll have to track down a static address because much information, such as your health points, are at a different dynamic address every time you load the game.To defeat it is simple, really. You can use cheat engine, even. You find the address for the current execution session, and run a BreakPointMemory on it.

    In CheatEngine you simply right click and select 'View What Writes To This,' and you will recieve hardcode. Your health be at address 7CB10EFF and thus if you wrote 40h to it, you'd have 60 health, but next time the game loads it'll be a different address and you'd either have to re find it, or predict it if you can. You can instead BPM it and come up with a hard location such as: 404D000 xxxxxxxxxx mov dword ptr ds:[eax],ebx in which you may learn [eax] is the 'current address' and ebx is your health to be loaded. You can replace ebx with 40 and give yourself 60 health every time the game loads, no matter what the

    [eax]/dynamic address is.

    Part 2. HowTo: Use DMA

    I actually designed my own method of dynamic memory allocation, that requests a new address each code cycle, instead of each application execution. This makes most memory searchers stop working at the 'scan next' and therefore is one of the simplest ways to stop over half the hackers out there. Here's an example of it, each time I take 10 damage:

    0x3d2488
    100

    0x3d3db0
    99

    0x3d3de0
    98
    If using cplusplus, you can simply read the Wrox C++ Tutorial, the DMA chapter, and figure out how to use it and apply my method. But to wrap up this lesson I will make show you the DMA function in ASM

    Code:
    MOV DWORD PTR SS:[ESP],ceme.004433C0
    CALL ceme.0043C1C8
    MOV DWORD PTR SS:[EBP-C],0
    MOV DWORD PTR SS:[ESP],8
    CALL ceme.00402380
    MOV DWORD PTR SS:[EBP-C],EAX
    MOV EAX,DWORD PTR SS:[EBP-C]
    FILD DWORD PTR SS:[EBP-4]
    FLD QWORD PTR DS:[440018]
    FSUBRP ST(1),ST
    FSTP QWORD PTR DS:[EAX]
    ...the requesting CALL is actually an MALLOC routine.

    Code:
    004023C6   > C745 C4 01000000   MOV DWORD PTR 
    SS:[EBP-3C],1                      ; |
    004023CD   . 8B45 08            MOV EAX,DWORD PTR 
    
    SS:[EBP+8]                     ; |
    004023D0   . 890424             MOV DWORD PTR 
    SS:[ESP],EAX                       ; |
    004023D3   > E8 48E40000        CALL 
    <JMP.&msvcrt.malloc>                        ; 
    malloc
    You can read further for more information. I don't do give aways, as you all know.

  12. #11
    Toymaker's Avatar
    Join Date
    Feb 2008
    Gender
    male
    Location
    Hannah, Montana
    Posts
    659
    Reputation
    14
    Thanks
    193
    My Mood
    Amused
    DaY 5:

    Introduction

    In today's dose I want to cover a few interesting concepts I was tinkering with recently...

    ...executing caves without calling them, manipulating api and stopping your application from being capable of closing....

    Practicality
    • Structured Exception Handling
    • Easy Hot Keys
    • Save Memory Space
    • Anti-Detection
    • Maleware potential



    p1. A the main executable of a game application works as an infinate loop, always changing as you play, such as refreshing the screen every instant with your chracters new coordinates. With this in mind, looking at a certain game I found, the last RETN of the entire main.exe before the caves start, can be replaced and thus avoid me needing to hook any specific function or call my own caves. I can also only modify 1 byte of game data rather than 5, as customary in calling...

    Code:
    004785C3  |> 5F                     POP EDI
    004785C4  |. 5E                     POP ESI
    004785C5  |. 5B                     POP EBX
    004785C6  |. C3                     RETN
    004785C7     00                     DB 00
    004785C8     00                     DB 00
    ...

    ...this is originally how the code ended. I thus did the following:

    Code:
    004785C6     51                     PUSH ECX
    004785C7     8B0C24                 MOV  ECX,DWORD PTR SS:[ESP]
    004785CA     C70424 1B000000        MOV DWORD  PTR SS:[ESP],1B
    004785D1     E8 A33D8D77            CALL  USER32.GetKeyState
    004785D6     83EC 04                SUB ESP,4
    004785D9     66:85C0                TEST AX,AX
    004785DC     74 05                  JE SHORT  004785E3
    004785DE     890C24                 MOV DWORD  PTR SS:[ESP],ECX
    004785E1     59                     POP ECX
    004785E2     C3                     RETN
    004785E3     E8 02483A7C            CALL  kernel32.ExitProcess
    004785E8    ^EB F4                  JMP SHORT  004785DE
    ...if you look closely you'll see I did many things. Firstly, I replaced the return with my own algorithm that will execute on it's own infinately, while you play.

    Secondly, you'll notice i did a getkeysync for the ESC key. If not pressed, it'll just return to normal game play, IF PRESSED, it will do our hack, which is a 'Call ExitProcess.' It will then return to game play after wards, except not in my example because I'm forcing termination.

    I'll give you a break down..

    PUSH ECX
    MOV ECX,DWORD PTR SS:[ESP]
    ...here, I am saving the original value of ESP and ECX, as to balance the returning and so forth...

    MOV DWORD PTR SS:[ESP],1B
    CALL USER32.GetKeyState
    ...here i am setting to check the keystate of 1B (ESC key). It will get the current keystate and compare it to escape for me...

    SUB ESP,4
    TEST AX,AX
    JE SHORT 004785E3
    ...here is where it restores balance and tests if the key was pressed or not. If so, it will jump to my hack...

    CALL kernel32.ExitProcess
    ...if not, or after that's done (not in this case, though), it will go to MY balancing and return to normal game play..

    MOV DWORD PTR SS:[ESP],ECX
    POP ECX
    RETN




    p2. Two things you can use from above, is knowing there is a variable in kerenel32 that always stores the last key pressed. I've used this information to make a virtually undetectable keylogger. I've also made a virtually undetectable gamehack by writing my parameters to parts of kerenel32 that always execute, and then calling the game functions myself.

    Any way, say you didn't want your application to be capable of exiting, well you could return all calls from ExitProcess most simply put. The example I give won't be perfect but: CALL 7C81CDEA is call ExitProcess.

    Quote Originally Posted by kerenel32
    7C81CDEA > 8BFF MOV EDI,EDI
    7C81CDEC 55 PUSH EBP
    ...as most functions, the stack frame begins as 7C81CDEC in which we can simply replace with a RETN...

    Code:
    7C81CDEC  C3 RETN
    ...now, theoretically, all calls to exitprocess will return immedaiately, if done right..good luck. This can be useful to adding more control over the games exception handling.

  13. #12
    Toymaker's Avatar
    Join Date
    Feb 2008
    Gender
    male
    Location
    Hannah, Montana
    Posts
    659
    Reputation
    14
    Thanks
    193
    My Mood
    Amused
    DaY 6:

    In today's Daily Dose, by Toymaker, I will be again creating our own hot key in order to change a variable in an example C++ program...

    The practical use is to understand how stack frames in memory allocate variables. Here's the C++ code...

    Code:
    #include <iostream>
    #include <windows.h>
    using namespace std; 
    int main() {
    int x = 0;
    if ( x == 0 ) {
         cout<<"hello choobn";
         }
         system("pause");
         if ( x == 1 ) {
         cout<<"bye choobn";
         }
         system("pause");
    }
    ...as you see, x is 0 so only the first string will print and the second will not. We are going to hack it, with our own hot key and variable modifier, so it prints both. In OllyDBG/ASM you'll see it...

    Code:
    00401390  /$ 55                               PUSH EBP
    00401391  |. 89E5                            MOV  EBP,ESP
    00401393  |. 83EC 18                         SUB  ESP,18
    00401396  |. 83E4 F0                         AND  ESP,FFFFFFF0
    00401399  |. B8 00000000                     MOV  EAX,0
    0040139E  |. 83C0 0F                         ADD  EAX,0F
    004013A1  |. 83C0 0F                         ADD  EAX,0F
    004013A4  |. C1E8 04                         SHR  EAX,4
    004013A7  |. C1E0 04                         SHL  EAX,4
    004013AA  |. 8945 F8                         MOV  DWORD PTR SS:[EBP-8],EAX
    004013AD  |. 8B45 F8                         MOV  EAX,DWORD PTR SS:[EBP-8]
    004013B0  |. E8 FBBC0000                      CALL Untitled.0040D0B0
    004013B5  |. E8 36B90000                      CALL Untitled.0040CCF0
    004013BA  |. C745 FC 00000000                MOV  DWORD PTR SS:[EBP-4],0
    004013C1     837D FC 00                      CMP  DWORD PTR SS:[EBP-4],0
    004013C5     75 14                           JNZ  SHORT Untitled.004013DB
    004013C7  |. C74424 04 00004400              MOV  DWORD PTR SS:[ESP+4],Untitled.00440000         ;   ASCII "hello choob
    "
    004013CF  |. C70424 C0334400                 MOV  DWORD PTR SS:[ESP],Untitled.004433C0
    004013D6  |. E8 ADAC0300                      CALL Untitled.0043C088
    004013DB  |> C70424 0D004400                 MOV  DWORD PTR SS:[ESP],Untitled.0044000D           ;  |ASCII "pause"
    004013E2  |. E8 B9F20000                      CALL <JMP.&msvcrt.system>                           ; system
    004013E7  |. 837D FC 01                      CMP  DWORD PTR SS:[EBP-4],1
    004013EB  |. 75 14                           JNZ  SHORT Untitled.00401401
    004013ED  |. C74424 04 13004400              MOV  DWORD PTR SS:[ESP+4],Untitled.00440013         ;   ASCII "bye choob
    "
    004013F5  |. C70424 C0334400                 MOV  DWORD PTR SS:[ESP],Untitled.004433C0
    004013FC  |. E8 87AC0300                      CALL Untitled.0043C088
    00401401  |> C70424 0D004400                 MOV  DWORD PTR SS:[ESP],Untitled.0044000D           ;  |ASCII "pause"
    00401408  |. E8 93F20000                      CALL <JMP.&msvcrt.system>                           ; system
    0040140D  |. B8 00000000                     MOV  EAX,0
    00401412  |. C9                               LEAVE
    00401413  . C3                               RETN

    ...do you notice...

    004013C1 837D FC 00 CMP DWORD PTR SS:[EBP-4],0
    004013C5 75 14 JNZ SHORT Untitled.004013DB
    ...is before both optional string prints? It is because [EBP-4] is X in C++! Each varaible is accessed through [EBP] as such, -4 for the first varaible and -8 for the second and it continues. Any way, beings the first message is bound to print regardless, we can replace these two lines with a call to our caves where we will allow the user to hot key the second message to print or not...

    Code:
    004013C1     E8 02DC0300                      CALL Untitled.0043EFC8
    004013C6     90                              NOP

    ...now we go to our caves and create our function, that if ESC is pressed, will set X to 1 so the second message, on your return, prints as well...

    Code:
    MOV DWORD PTR SS:[ESP],1B
    CALL GetKeyState
    SUB ESP,4
    TEST AX,AX
    JNZ 01                             
    RETN
    MOV DWORD PTR DS:[EBP-4],1                        
    RETN
    ...if ESC was pressed, it will set [ebp-4]/x to 1, and thus the second message will also print. Our educational hack now allows both messages to print...
    Last edited by Toymaker; 06-25-2009 at 01:58 PM.

  14. #13
    Dave84311's Avatar
    Join Date
    Dec 2005
    Gender
    male
    Location
    The Wild Wild West
    Posts
    35,837
    Reputation
    5782
    Thanks
    41,292
    My Mood
    Devilish
    Very interesting so far sir.





    THE EYE OF AN ADMINISTRATOR IS UPON YOU. ANY WRONG YOU DO IM GONNA SEE, WHEN YOU'RE ON MPGH, LOOK BEHIND YOU, 'CAUSE THATS WHERE IM GONNA BE


    "First they ignore you. Then they laugh at you. Then they fight you. Then you lose.” - Dave84311

    HAVING VIRTUAL DETOX

  15. #14
    Jakor's Avatar
    Join Date
    Feb 2008
    Posts
    48
    Reputation
    10
    Thanks
    0
    Day 5:
    Quote Originally Posted by Toymaker View Post
    Code:
    004785C6     51                     PUSH ECX
    004785C7     8B0C24                 MOV  ECX,DWORD PTR SS:[ESP]
    (...)
    004785DE     890C24                 MOV DWORD  PTR SS:[ESP],ECX
    004785E1     59                     POP ECX
    (...)
    Did you even look at this? Here is a daily dose of why Assembly > C...

    lets watch the stack... Assume on entry ecx == 11111111h
    first command:
    push ecx aka add esp, 4 then mov dword ptr [esp], ecx
    next command:
    mov ecx, dword ptr [esp] (wait didn't we just put ecx ON the stack?)
    next:
    (...) assume we change ecx in here with a fast call it's now 22222222h
    next:
    mov dword ptr [esp], ecx (stack was 11111111h now rewrite it with 22222222h)
    then:
    pop ecx aka mov ecx, dword ptr [esp] then sub esp, 4 (yes, we just wrote ecx to the stack and are removing it from the stack again...)
    on return:
    ecx == 22222222h when it should be 11111111h :-\

    the code there does nothing and is just garbage from a C compiler.

  16. #15
    Toymaker's Avatar
    Join Date
    Feb 2008
    Gender
    male
    Location
    Hannah, Montana
    Posts
    659
    Reputation
    14
    Thanks
    193
    My Mood
    Amused
    I think I confused you in two ways, Jakor...

    • Those four lines were input BY ME in Olly manually. If you do know this, never mind, continue to the next line of explanation.
    • I crudely rough drafted the tutorial and I didn't make sure any of it was specifically accurate, my bad. I only meant to make a point of using ecx to store the original ESP before I used it twice more, in GetKeyState. It was the simplest balance with so much trouble on the way.


    ...I assume you also read day 6? I am writing day 7 as we speak and adding it to this very post tonight, teehee. It's going to include some methods I invented...
    Last edited by Toymaker; 06-24-2009 at 07:01 PM.

Page 1 of 3 123 LastLast

Similar Threads

  1. I-doser 4.5 with all doses
    By djtwistter01 in forum Hardware & Software Support
    Replies: 0
    Last Post: 07-09-2007, 01:27 AM
  2. Clinton on the Daily Show
    By Dave84311 in forum General
    Replies: 1
    Last Post: 09-20-2006, 10:44 PM
  3. Replies: 2
    Last Post: 08-06-2006, 08:03 PM
  4. dose any1 know were 2 get tv episodes
    By sqeak in forum Suggestions, Requests & General Help
    Replies: 8
    Last Post: 02-19-2006, 06:10 AM
  5. The Daily Show
    By Chronologix in forum Entertainment
    Replies: 2
    Last Post: 01-19-2006, 03:20 PM

Tags for this Thread