Saturday, March 24, 2012

My article: Analysis excute code of easy program in Vietnamese

Demo disassembly

Mở file vidu.exe, chọn E ( excute), chọn tới vidu.exe
Ta thấy nội dung chương trình sau khi disassemly. Đây chính là code thực thi của chương trình:
Trước tiên cần tìm chương trình chính, source code là:
#include
int tong(int a, int b)
{
    int t=0;
    t=a+b;
    return t;
}
int main (){
printf("Ket qua: %i",tong(1,2));
return 0;
}
Nhận thấy là có một chương trình con là tính tổng, như vậy trong chương trình chính sẽ gọi hàm tong với 2 tham số truyền vào là 1 và 2. Sau đó, hàm main sẽ phải in ra “Ket qua: “.
Với 2 dữ kiện đó, chúng ta tạm xác định hàm main bắt đầu từ: 00401020
Vì:
Bắt đầu bằng việc PUSH EBP và MOV EBP,ESP. Việc này là thủ tục đầu tiên khi gọi hàm.
Tiếp theo, hàm main sẽ gọi hàm tính tổng. Tại sao?
Ở vị trí 00401023, tiến hành PUSH 2 rồi tiếp theo PUSH 1. Đây chính là quá trình truyền tham số cho chương trình con thông qua stack ( hoạt động theo cơ chế LIFO). Các tham số được push vào theo chiều ngược lại với code là từ phải qua trái. Tiếp đến, hàm main sẽ tiến hành call một hàm ở vị trí 00401000. EIP đang lưu lệnh được thực thi tiếp theo sẽ được cất vào trong stack:
Ban đầu, giả sử stack sẽ là:
Tiếp theo là PUSH EBP và MOV EBP,ESP
PUSH tham số 2 và 1 vào chuẩn bị gọi chương trình con tong():
Gọi chương trình con tong(), khi lệnh CALL thực hiện, EIP lưu lệnh quay trở về được lưu vào stack:
Chương tringh con bắt đầu bằng việc lưu lại giá trị của EBP ( EBP của hàm main), kết thúc ESP lúc này trỏ vào vị trí mà EBP vừa được push vào:
00401000  /$  55            PUSH EBP
Tiếp đến, cập nhật giá trị EBP mới ( EBP của chương trình con tong):
00401001  |.  8BEC          MOV EBP,ESP
Lúc này EBP và ESP cùng trỏ tới một chỗ:
Tại sao phải sử dụng EBP. Ở phần sau chúng ta sẽ thấy rõ việc sử dụng EBP. EBP là base pointer, được sử dụng để tham chiếu các biến.
00401003  |.  51            PUSH ECX
Lệnh này chính là cấp phát vùng nhớ biến t (4bytes bằng kích thước của ECX) , sau khi kết thúc, ESP di chuyển xuống 4bytes.
Lệnh tiếp theo:
00401004  |.  C745 FC 00000>MOV DWORD PTR SS:[EBP-4],0
Lệnh này sẽ sao chép giá trị 0 đến vị trí EBP – 4. Stack phát triển từ cao xuống thấp, nên trừ 4 chính là EBP trỏ đến giá trị t vừa được cấp phát. Kết thúc lệnh này, biến t sẽ được khởi tạo giá trị bằng 0:
Lệnh tiếp theo: 0040100B  |.  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]
Sẽ sao chép giá trị của EBP cộng 8, chính là vùng lưu giá trị 1 vào EAX:
Lệnh tiếp theo:
0040100E  |.  0345 0C       ADD EAX,DWORD PTR SS:[EBP+C]
Lấy giá trị EBP + 12 ( C trong hệ cơ số 16 là 12, vùng nhớ này có giá trị là 2) cộng với EAX. Kết quả lưu vào EAX, nên EAX có giá trị là 3.
Lệnh: 00401011  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
Lệnh trên lưu giá trị EAX vào EBP trừ 4, chính là biến t. Lúc này t sẽ bằng 3:
Lệnh: 00401014  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
Lệnh này sao chép giá trị t vào EAX. Các chương trình con sau khi thực thi cần có giá trị trả về, giá trị trả về này được lưu vào EAX.
00401017  |.  8BE5          MOV ESP,EBP
Lệnh này, ESP sẽ trỏ vào EBP đang trỏ, đây chính là nơi lưu giá trị EBP của hàm main:
Lệnh 00401019  |.  5D            POP EBP
Lệnh thực hiện, EBP của hàm main đã lưu sẽ được lấy ra, giá trị lưu vào EBP. Có nghĩa là hồi phục lại giá trị EBP của main đã lưu. Kết thúc hàm này ESP giảm xuống 4bytes:
Lệnh 0040101A  \.  C3            RETN
Tiến hành lấy lại EIP đã lưu, EIP trỏ lại về chương trình chính tại sau lệnh call:
ESP sẽ giảm tiếp 4bytes nữa ( 4bytes đã lưu EIP trước đó)
Quay trở lại chương trình chính.
Lệnh 0040102C  |.  83C4 08       ADD ESP,8 thực thi. ESP giảm thêm 8bytes bằng độ lớn của 2 biến tham số đầu vào 1 và 2:
Lúc này, giá trị trả về của hàm vẫn đang được lưu trong EAX. Lệnh
0040102F  |.  50            PUSH EAX  được thực thi, giá trị của hàm được đẩy vào stack.
Tiếp theo là lệnh:
00401030  |.  68 00C04000   PUSH vidu.0040C000                       ;  ASCII "Ket qua: %i"
Lệnh đẩy tiếp tham số là một chuỗi được định nghĩa sẵn ( tại vùng nhớ 0040C000). Đây chính là 2 tham số đầu vào cho hàm printf().
Sau khi truyền tham số xong, hàm printf() được gọi:
00401035  |.  E8 07000000   CALL vidu.00401041
Quá trình gọi hàm con tương tự, cũng lưu EIP rồi EBP, ESP thay đổi tăng giảm. Kết thúc hàm xâu “Ket qua: 3” sẽ được in ra, quay trở lại chương trình chính main thực thi tiếp:
0040103A  |.  83C4 08       ADD ESP,8
Lệnh này tương tự như trên vì cũng truyền vào stack 8bytes ( 2 thanh ghi 4bytes nên giờ phải tăng 8bytes)
0040103D  |.  33C0          XOR EAX,EAX
Hàm printf() không có kết quả trả về nên tiến hành  XOR để xóa trắng EAX.
0040103F  |.  5D            POP EBP
Trả lại EBP cho chương trình gọi hàm main(), có nghĩa là trả lại EBP của môi trường.
00401040  \.  C3            RETN
Chương trình vidu.exe đã được thực hiện xong.
------------------------------------------------------------
Thanks for reading
--------------------------------------------------------------------------
All my Lab:
Linux Lab -- window and Cisco Lab
to be continued - I will update more.  

No comments:

Install Xposed Inspector and Frida on Genymotion

Today i had some work with android. So i need trace application. I found 2 nice tool can help me: Xposed Inspector and Frida. To setup ther...