Windows x86 kernel (1)

Getting Started

Common assembly instructions

stack related instructions

push: Push a 32-bit operand onto the stack. esp-4.
pop : esp+4, the data is popped from the stack.
sub : Subtraction. The first parameter is the register where the minuend is located, and the second is the subtrahend register.
add : Similar to sub.
ret : return. Equivalent to jumping back to where the function was called. (The corresponding call instruction to call the function, and return to the startling instruction after the call)
call : call function/

  • The essence of call is equivalent to push+jmp
  • The essence of ret is equivalent to pop+jmp

    sub, add can also be used to manipulate the stack. If you need a 4*4 long shaping space, there is no need to push 4 times, but esp-16.

data transfer instruction

mov : data movement. The first parameter is the destination and the second is the source.
xor : exclusive or.
lea : Get the address (the second parameter) and put it into the previous register (the first parameter).

  • xor eax,eax is to clear xor
  • lea is used to do the same thing as mov, but the second parameter of mov is a register and cannot be calculated
  • eg: mov edi, esp-0cch, is wrong, change mov to led

stos : String storage instruction.

mov  ecx,30h
mov  eax,0cccccccch
rep  stos dword ptr es:[edi]

The function of this sentence is to put the data of eax into the address pointed to by edi, and at the same time, edi+4.
rep causes the instruction to repeat the number of times filled in ecx. Square brackets indicate memory, which is actually the address pointed to by the content of edi. Here stos is actually stosd, and others include stosb and stosw, which handle 4, 1, and 2 bytes respectively.
The content here is to initialize the 30h*(0c0h) bytes in the stack to 0cch (that is, the int 3 instruction machine code), so that when an exception occurs, the contents of the stack will cause a debug interrupt.

jump comparison instruction

cmp: Compare.
jmp : Unconditional jump.
jg : Jump when greater than, usually preceded by cmp.
jl : Jump when less than, usually preceded by cmp.
jge : Jump when equal, usually preceded by cmp.

C function parameter passing process

Basic knowledge

C language passes parameters from outside the function to the inside of the function through the stack, and divides the area in the stack to accommodate the internal capacity of the function.

The stack side is always that the caller pushes the parameters onto the stack in reverse order (from right to left), and the callee restores the stack.
These parameters are aligned to the machine word length, 16-bit, 32-bit, and 64-bit CPUs are aligned to 2, 4, and 8 bytes, respectively. This always calls is the C compiler default.

Function calling rules:
(on Window)

  • cdecl C calling rules:
    (1) Parameters enter the stack from right to left.
    (2) After the function returns, the caller is responsible for cleaning up the stack. So such calls often generate larger executable programs.
  • _stacall is also known as WINAPI, and its calling rules:
    (1) Parameters enter the stack from right to left.
    (2) The called function cleans up the stack by itself after returning money, so the code produced is smaller than cdecl.
  • There is also a Pascal
    that is roughly the same as _stacall, except that it does not support function calls with variable parameters, mainly for Win16.

technical details

Write a function to verify

void myfuc(int a,int b) {
        int c=a+b;
}

This is the standard C way of calling.
[1] The caller pushes the parameters onto the stack in reverse order.
[2] Call the function.
[3] The caller cleans up the stack and restores it.

  • In Windows, no matter what kind of call is made, the return value is placed in eax, and then returned. The external gets the return value from eax.

The _cdecl method calls a function generally to do the following things:

(1) Save ebp. ebp is always used by us to save the value of esp before this function was executed. After execution, we restore esp with ebp.
(2) Save esp to ebp.
That is (3) allocate space by esp-4, that is, allocate 4 bytes of space. When restoring, just restore the esp to the data saved in the ebp. (4) Save ebx, esi, and edi to the stack, and restore after the function is called.
push ebp
mov ebp,esp



The corresponding code is as follows:

sub esp,0cch
push ebx
push esi
push edi

(5) Initialize the local variable area to all 0ccccccch. 0cch is actually the machine code of the int3 instruction, which is an interrupt instruction. Because local variables cannot be executed, if executed, there must be an error in the program, and an interrupt occurs to prompt the developer. This is NX protection, the stack is not executable.

lea edi,[ebp-0cch]

mov  ecx,33h
mov  eax,0cccccccch
rep  stos dword ptr es:[edi] //串写入

(6) Then do what the function should do. The acquisition of parameters is that ebp+12 bytes are the second parameter, and ebp+8 is the first parameter (note that it is poured into the stack), increasing in turn. The last ebp+4 byte is the address to be returned.

(7) Restore ebx, esi, edi, esp, ebp, and finally return.

pop  edi
pop  esi
pop  ebx
mov  esp,ebp

pop ebp
ret

Note that if there is a return value, put the return value in eax. The external gets the return value through eax.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324780227&siteId=291194637