Hot answers tagged

129

Such small snippets are not too hard to decompile manually. Let's try it. You have already figured out that cl holds a character, this means that eax where it's read from is a pointer to a character array. Let's call it p. Now, let's do a dumb translation for every assembly statement to C: l1: ; l1: mov cl, [eax] ; cl = *p; cmp cl, ' ' ; ...


21

Here is the list of few decompilation tools / resources that you may find useful. IDA Pro + Hex-Rays decompiler Hopper disassembler (has a decompiler) ODA (Online Disassembler) Retargetable Decompiler Boomerang (decompiler)


21

Register eax will contain the return code from strcmp, after the call. The test eax, eax is the same as and eax, eax (bitwise and) except that it doesn't store the result in eax. So eax isn't affected by the test, but the zero-flag is, for example. The test eax, eax is necessary to make the jne work in the first place. And jne is the same as jnz, just as je ...


16

Main is usually a programmer-defined entry point, while entry is defined by the compiler, it's doing many other operations such as libc initializations, heap allocation, and so on, and eventually, call the user-defined main entry point. You can see main as a callback function that defined by the user and eventually called by entry.


15

The pc command will output n bytes from the current seek (s) as a C array, where n is the Block size (b) or the length mentioned in the command. The output is then can be used to, for example, manipulate the array outside of radare2, build a shellcode, decrypt a buffer and so on. Let's demonstrate it with a simple example. Here's a tiny HelloWorld.c ...


14

All Hex-Rays macros are defined in <IDA directory>\plugins\defs.h. It's also available at https://github.com/nihilus/hexrays_tools/blob/master/code/defs.h For BYTE3(x): ... #define BYTEn(x, n) (*((_BYTE*)&(x)+n)) ... #define BYTE3(x) BYTEn(x, 3) ... So BYTE3(x) yields (*((_BYTE*)&(x)+3)), which effectively means the fourth byte of the ...


14

These suggestions may help. One sure way of becoming a better reverse engineer is to become a better "forward engineer"! Here's what I would suggest: Examine the assembly output of various compilers. Write test programs of increasing complexity and examine the assembly language output so that you get a sense of what the compiler does for any given high ...


14

Here is exact answer to you question. Go to http://www.tutorialspoint.com/compile_assembly_online.php Doubleclick on main.asm in upper-left corner of the screen Copy your snippet to the text window. You'll need to add definition of data and make some tweaks, my resulting assembly code is section .text global main main: xor ebp,ebp mov dword [...


13

rECX = (rECX & 0xFFFFFF00) | ((rECX & 0xFF) >> 1)


13

If you look at the disassembly of authorize() I'm sure you'll find that the compiler is pushing and restoring more registers than just EBP or aligning the stack. I would recommend that you always look at the disassemly when dealing with overflows of various kinds. The compiler and decompiler, if you use one, hides a lot of details. The disassembly never lies ...


12

EDIT: @EnricoGhirardi Thanks for pointing the mul esi inaccuracy I previously posted! To start out, the first instruction mul esi zeroes out rax and rdx in the example below (this is only because rsi is 0 to begin with). The least significant bits will be stored in rax and the most significant bits will be stored in rdx. Both of these registers will be zero....


12

You might be missing the fact that call strcmp will not set ZF for you - it returns the result in the EAX register. But JNE instruction tests ZF, and that test eax, eax serves to set ZF according to EAX. (actually, the opposite way, EAX=1 -> ZF=0). I recommend reading some easy book on x86 assembly, it will help you a lot.


11

functionpointer is declared before char buffer[50]; on the stack so How comes it overwrites it ??? The order of objects in the stack is implementation defined. C does not mention any stack and the direction of the stack growing is also implementation-defined (usually it grows downwards but in some systems it grows upwards). In your case functionpointer is ...


11

Why does the return address have to point to the shellcode in the same buffer? It doesn't, but generally, both the shellcode and the return address are delivered at the same time, so they are stuck together for that reason. If your exploit allows you to deliver them separately, then they can be separated. However, they are by necessity both local to the ...


11

What you're seeing is an efficiency trick that compilers like to use. Internally, the CPU doesn't make a difference between numbers and addresses - 32 bit integers and pointers are the same thing. (Or 64 bit, if you're using newer architecture, but as your register names start with e, you're using 32 bit). The lea instruction loads the address of its ...


10

Well, especially for that, Hex-Rays Decompiler was invented. It will decompile ASM code into pseudo-C, and from there You may write C-based logic of assembly code You have.


10

First it should be noted that there are so many architectures out there, each with its own instruction set. Here I assume you mean x86 (and you should indeed tag the proper architecture as 0xC0000022L said above). Most parts of the below answer would apply to other architectures as well, but they may use different mnemonics or lack some mentioned ...


8

The compiler did put the function pointer after the buffer. In the disassembly, check the memcpy call: 8048525: lea -0x58(%ebp),%eax 8048528: mov %eax,(%esp) 804852b: call 804838c <memcpy@plt> The first argument to memcpy (the buffer's address) is at [esp+0] and you can see that the value of ebp-0x58 is being put there. Next is the ...


8

It's a binary search. I've renamed several of the variables, and in one case, introduced a new variable, because one of the local variables was used for one thing in the first half of the function and something else in the second half of the function. The only tricky part is that once it finds an occurrence of the string to find, it iterates to find the ...


8

You don't need to bypass gcc's stack smashing detection. If you overwrite key correctly, you get an interactive shell before the stack check is performed at the end of func(). Here's the proof in the form of a Python script: import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("pwnable.kr", 9000)) s.send("A"*52 + "\xBE\xBA\xFE\xCA" ...


8

The answer from Jason is the correct solution. However, I wanted to give an alternative answer without Python, but from the terminal. IMO Python is always preferred for better automation, but sometimes you just wanna have a quick exploit done without extra tools. With that in mind, one's natural attempt would be something like below: echo -e "...


8

prototype of strcmp() int strcmp( const char *string1, const char *string2 ); the function returns an int whose interpretation is as follows so i think that answers your question of when it jumps and when not it jumps if eax is either > or < 0 it does not jump if eax == 0 Return Value The return value for each of these functions indicates ...


8

This is such a small program so this could be followed without converting it back to C. Let's break it down what happens when it's being called with asm(0xb6, 0xc6). push ebp mov ebp, esp Those two lines are what's is called the function prologue. We first save the calling function stack frame (ebp is tracking that) and in the second one, we set our ...


8

There are ways to make a Python program hard to reverse engineer. Its' possible but you need to fiddle with the Python source code (which is written in C) and compile a special build for your purpose. The way Python works is fully documented and open-source. For instance, consider the pyc file format. Much of the code which deals with reading/writing pyc's ...


7

You cannot prevent reverse engineering. You can make it more or less harder but you cannot prevent it. No. Update Ok, as the author updated it with a more clearer question... this is what one can do: Strip symbols from the binaries. At the very least. Obfuscate the code. This may help: https://stackoverflow.com/questions/4111808/c-c-compiler-generating-...


7

The C compiler doesn't create any assembly code to declare and initialize global fundamental data types, so you won't see anything like MOV ..., 3 in OllyDbg for your program above. In the disassembly of your program below, you can see that the global variable is stored at dword_402000, which is hardcoded to begin with a value of 3:


7

The answer above is correct for the most part but it includes some inaccuracies. I can't comment so I'll add the corrections in this answer. First I don't think this is a good shellcode since it takes an assumption on both %rax and %rsi. @itsbriany correctly points out that %rax is zero, but that is the case only in the specific launcher that the author ...


7

If your application can decrypt the files, then you should assume that anyone sufficiently interested can do so as well. End of story. Obfuscation can slow people down, but it won't stop everyone, and it probably won't be as effective as you think it will be.


7

Although rewriting assembly to pseudo C is not technically reverse engineering, I'll try to help init: mov eax, [ebp+8] push eax mov eax, [ebp+0xc] push eax mov eax, [ebp+0x10] push eax mov eax, [ebp+0x1c] puse eax xor ecx, ecx This block just basically sets up parameters, as already mentioned ecx is a counter. loop: xor ...


6

if you determined the argv and argc and values in there you gone half of the way . from value of argc you can understand how many arguments you should pass and from values in argv you can determine what you "should" pass. i wrote a very simple example for you 70 _main proc near ; CODE XREF: _main_0j .text:00401070 .text:00401070 ...


Only top voted, non community-wiki answers of a minimum length are eligible