History view

Cracking

Binary patching 0x2

theFaunia in the wild 2019. 11. 9. 02:44

Index of course:

  • Basics of reverse engineering.
  • Binary patching of real-world software.
  • Backdoors.
  • Testing software for vulnerability research.
  • Exploit development.

Basics of reverse engineering

Reversing, is to find out from a «product» that its inverse process is finished. In the case of computer science from a binary or software know its source code, interpreting the high level language that was used in the development of the program. Knowing the operation of the CPU a hacker will be able to obtain the source code from the binary.  

The x86 assembly language is the family of assembly languages ​​for the x86 family processors, with the Intel 8086 processor being the first. Use a series of mnemonics to represent the fundamental operations that the processor can perform. The x86 has 2 different aspects in terms of its programming syntax: Intel syntax, used at the beginning for the documentation of the x86 platform, and AT & T syntax. Intel syntax is the dominant one in the Windows platform. We will use the Intel syntax in the entries.  We see the first instructions that can be found in a main function, in assembly language.

Prologue of main function

Each Byte corresponds to 8 bits and can be interpreted as 2 hexadecimal digits. In the first instruction the "55" in hexadecimal corresponds to 1 Byte, and each Byte is assigned a memory address.

On the left side the hexadecimal numbers correspond to the memory addresses. Bytes of the machine language instructions in the central part must be stored somewhere being in memory, numbered with addresses. These bytes in hexadecimal correspond to the instructions in machine language for 32-bit processors, x86. They are representations of the binary system that the CPU understands, that is to say something like this 1010110110 ... The hexadecimal system uses base 16, from 0 to 9 and from A to F to represent values ​​between 10 and 15. 

The CPU can access each Byte through its memory address and thus obtain the machine code instructions that make up the compiled program. As you can see in the second instruction "Mov" we see 2 bytes and each of them in a different memory address (0x08048405 and 0x08048406). 
There is a close relationship between assembly language and machine instruction by instruction language, which differentiates it from high-level or compiled languages. Therefore, the assembly language is a representation of the machine language instructions that are sent to the processor. Each instruction of the x86 is represented by a mnemonic, which translates directly to a series of bytes the representation of the instruction, called the operation code.For example, the NOP instruction is encoded as 0x90 in hexadecimal. 
The instructions make use of the processor registers to be able to perform a series of actions such as moving data or memory addresses, or performing arithmetic or logical operations. 
These registers are:

  • EAX, EBX, ECX, EDX: These are general purpose records. Accumulator, base, counter and data respectively. They can save both data and addresses. 

Basic instructions

The MOV instruction: It allows us to move content or memory addresses from source to destination, following this structure mov dest, orig. ADD allows adding the result being stored in destination. SUB is the same but in subtraction.  

  • EBP, ESP: These are base and stack pointer records. ESP (Extended Stack Pointer) is the current pointer of the stack. EBP is the current basis of the stack frame, it is used to reference local function variables in the instructions of a function.
  • EIP: It is the registration pointer of the next instruction to execute. 
  • EDI and ESI. Destination and origin pointers.

Sections

The text segment contains the machine code of the compiled program, where the assembled instructions are located. It includes all the functions of the program, and its execution is not linear including the different conditional jumps due to the control structures. This segment has a fixed size. The text segment of an executable object file is often a read-only segment that prevents the program from accidentally changing and does not store variables, just code. Hence the name also of code segment. 
 
The data segment stores the program data. This data could be in the form of initialized or non-initialized variables (segment bss), and could be local or global.The bss its variables are initialized to zero or have no explicit initialization in the source code. It also has a fixed size, but it can be write segment unlike the text segment, since the value of the variables can be modified at runtime. 

Memory

Heap is not managed automatically, it is a manual task controlled by the developer. It has no fixed size and grows towards the highest memory directions as opposed to the Stack. The memory allocation in the Heap is achieved through the functions of C, malloc (), calloc () or new in the case of C ++. The stored variables are global. 

Stack temporarily stores arguments and local variables to the call of a function of our program. 

Stack

When a function is called, a space is left in the stack for local variables. This space is referenced by EBP with the variables above and below the saved EBP, return address and arguments. The ESP will move to allow that space to the variables towards the lowest memory addresses. The function will be logically located in another memory address, and is referenced when called. The stack grows towards the lowest memory addresses. 

By this I mean the following. The first three instructions of the function, configure the stack or stack, and receive the name of prologue or "Standard Entry Sequence" functions that vary according to the compiler and its options. We are talking about: 

 

Prologue of function

What these three instructions do is:

  • Place the base pointer on the stack or the Saved EBP.
  • Move the contents of the stack pointer to the base pointer in order to place the latter on the top of the stack.
  • Subtract the value in hexadecimal 0x18 from the base pointer, in order to leave space in the stack available for local variables. You can see this in the image of the Stack, appreciating how the ESP is above (or in the lowest addresses of the stack) of the variables. 

Binary patching 

We start with the course choosing other software being Video Rotator 4.4. Below you have the software installation link:

https://download.cnet.com/Video-Rotator/3000-13631_4-75792431.html

First we see that the software was developed in Visual Basic. Therefore, seeing the APIs that are used, StrCmp is interesting and a lso VarCmpEq .

Visual Basic API's

Once the breakpoint is set, we execute the debugger and see that if we register the product, we will stop debugging the API call. 

Register Video Rotator Now!

Once for the execution where we have control, that is, we enter the product key and we can see it in memory.

Our input

However, from this point I began to debug step by step up to the application code. I was able to identify strings like "Invalid" and some strings in capital letters and numbers.

Maybe if we put one of those strings do not take the JE conditional jump. 

Invalid Code

Yes, now I don't jump, but invalid code. We could try to patch this JE conditional jump to JNE. Nothing happen. 

Try harder

So we just put a random string as product key and follow debugging. We can see that there is a special version experied with some kind of key: VR1I3D4CHIP. So we try with this key. 

Special Version

Okk but we dont want the MessageBox ...

MessageBox

So we just can modify the conditional jump to bypass The Special Version Expired MessageBox.

Bypass and patch

And I win! Registered program.

Cracked software

 

'Cracking' 카테고리의 다른 글

Binary patching 0x4  (0) 2019.11.18
Binary patching 0x3  (0) 2019.11.18
Introduction and purpose 0x1  (0) 2019.10.30
Comments