blueduece2 (06-03-2009),hbk (07-08-2009),PlSlYlClHlO (06-03-2009)
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:
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:004013C6 |. C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 004013CD |. E8 8EF20000 CALL <JMP.&msvcrt.exit> ; exit
...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:mov esp,0 call ExitProcess
Code:004013BA |> C70424 1B000000 /MOV DWORD PTR SS:[ESP],1B ; | 004013C1 |. E8 0AF50000 |CALL <JMP.&USER32.GetKeyState> ; GetKeyState...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.Code:mov esp,1b call GetKeySync
Last edited by Toymaker; 06-04-2009 at 04:28 PM.
blueduece2 (06-03-2009),hbk (07-08-2009),PlSlYlClHlO (06-03-2009)
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...
...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.Code:EB = JMP 74 = JE 75 = JNE E9 ## ## ## ## = If Far Jump
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
...for example. I can find some random point in memory and tamper with it to demostrate these ends, withoutCode:7C97DDE2 0000 ADD BYTE PTR DS:[EAX],AL 7C97DDE4 0000 ADD BYTE PTR DS:[EAX],AL 7C97DDE6 0000 ADD BYTE PTR DS:[EAX],AL
causing errors as so
I look at
There is not enough space to make a 5 byte long jump to our caves but it's okay because we can restoreCode:7C9012A4 897A 04 MOV DWORD PTR DS:[EDX+4],EDI 7C9012A7 0BFF OR EDI,EDI
memory at it. I'll write it
I completely ruined the original first two offsets but i can handle it by writingCode:7C9012A4 E9 39CB0700 JMP ntdll.7C97DDE2 ... 7C9012A9 74 22 JE SHORT ntdll.7C9012CD
...to my caves and now every thing is the same, and functions as so, but I added spaceCode:7C97DDE2 897A 04 MOV DWORD PTR DS:[EDX+4],EDI 7C97DDE5 09FF OR EDI,EDI 7C97DDE7 ^E9 BD34F8FF JMP ntdll.7C9012A9
to active memory for my modifying. That concludes DaY 2
toymaker i guess i am not getting in..huh?
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.
...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:call 4040D00
...versus...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
...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:004013E1 |. C70424 10004400 MOV DWORD PTR SS:[ESP],Untitled.00440010 ; |ASCII "pause" 004013E8 |. E8 93F20000 CALL <JMP.&msvcrt.system> ; system
...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.Code:system("pause");
In conclusion, i'll show you a basic example of assembly obsfucation. The normal c++ code for the above was:
...so now what I will be doing isCode:cout<<"Enter Passwordn"; system("pause");
...this is the new form, better hidden, in disassemblyCode:#define say cout<< char* urPrompt = "enter passwordn"; say urPrompt;
...You notice there's no ;text hint telling you the message now? The pointerCode: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
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.
Day 1I 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:
See code section above for same mistake... (should be mov dword ptr [esp],1b)Code:mov dword ptr [esp],0 call ExitProcess ;or JMP.&msvcrt.exit
However, if you are writing code in assembly / debugger take note of the two lines below:
which one do you think is more efficient?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)
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.
walking through this from start:Code:function proc arg:DWORD ret 4 function endp start: push 00 call function mov dword ptr [esp], 0 call function ret
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.
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.
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.
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.
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).
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).
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.
That's what I said he should do a tutorial on at some point.
I don't see how it would be irrelevant. I do it all the time and only use "assembly".
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.
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...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
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:
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 ASM0x3d2488
100
0x3d3db0
99
0x3d3de0
98
...the requesting CALL is actually an MALLOC routine.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]
You can read further for more information. I don't do give aways, as you all know.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
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:
...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.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
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..
...here, I am saving the original value of ESP and ECX, as to balance the returning and so forth...PUSH ECX
MOV ECX,DWORD PTR SS:[ESP]
...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...MOV DWORD PTR SS:[ESP],1B
CALL USER32.GetKeyState
...here is where it restores balance and tests if the key was pressed or not. If so, it will jump to my hack...SUB ESP,4
TEST AX,AX
JE SHORT 004785E3
...if not, or after that's done (not in this case, though), it will go to MY balancing and return to normal game play..CALL kernel32.ExitProcess
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.
...as most functions, the stack frame begins as 7C81CDEC in which we can simply replace with a RETN...Originally Posted by kerenel32
...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.Code:7C81CDEC C3 RETN
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...
...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:#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"); }
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...
...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...004013C1 837D FC 00 CMP DWORD PTR SS:[EBP-4],0
004013C5 75 14 JNZ SHORT Untitled.004013DB
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...
...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...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
Last edited by Toymaker; 06-25-2009 at 01:58 PM.
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
Day 5:
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.
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.