Zeroska
  • 🐱Zeroska - The Bold
  • Computer/Cyber Security
    • ⭐Fresh off the boat - for new Blue Teamer/ SOC Analyst
    • 💀Necromancer (DFIR)
      • 🕵️DFIR and DFIR case
        • 🗃️Case Files
          • Misconfiguration 0x01
      • 📔My own DFIR notes
        • The Mark of The Web (MOTW)
        • LNK Shortcut
        • Prefetch, AmCache, ShimCache in Windows
        • Malicious Document (VBA, Office, PDF, ...)
        • SRUM (System Resource Usage Monitor)
        • Volatility notes
        • Understand Logon Session in Windows
        • "Very" Hidden sheets in Excel
        • Hidden Processes
      • 📔Notes
        • Useful Resources
        • Useful Resources DFIR
        • Saved Content (Backup for the OG content get deleted)
          • How to be best SOC analyst ever
    • 🧙‍♂️Defense Witchcraft
      • Data Analysis as a Defender
      • Active Directory
      • Windows Event Logs
        • Authentication (Windows Account Life Cycle Events)
      • MS Exchange
      • Windows
    • 💙My Current Blue Team Operation
      • VLAN Monitoring Template
      • Daily Monitoring Report
      • General Playbook
      • JupyterHub Configuration Guide
      • How to train your Blue Team
    • 🏭ICS/OT
      • Setup ICS/OT Simulation Learning Lab
      • Smart Grids
      • Learning Modbus TCP
      • Learning DNP3
      • Resources/Blogs/Links
    • 🥷Threat Intelligence
      • Small Cyber Threat Intelligence Program
      • Intelligence Analysis [VN]
      • OSINT Information Monitoring
        • Telegram Info-Stealer Monitoring
      • C2 Tracker
      • Fake Website Tracker
      • Dark Web Investigation Attempt
      • Threat Intelligence Quick Win
      • Resources/Blogs/Links
  • 😒Computer and Technology
    • My Home Lab Setup
    • 🐴ELK Stack
      • Useful Resources
      • ELK Stack - Container - Docker Compose - AWS ECS
      • ECS - Elastic Common Schema
      • Elasticsearch
      • Logstash
      • Troubleshooting and Problems
    • 🐧Linux
      • Setting up good SSH Authentication
      • Configure Auditd and how to leverage it
      • ELF Format
      • Useful Links
    • 📦Containers
      • Docker container logs is quite big
      • Worth Reading
    • 🪠Splunk Learning Experience
      • Splunk Test Lab
      • Data Collection Tier (How to get the data)
      • SC4S Custom Filter For Windows Event Log in Syslog Format (NXLog)
      • Useful Resources
  • Threat Hunting
    • Hunting for Implant
    • Using STRIDE and DREAD
    • 🐳Predators and Preys (Computing)
      • Tracks or Hunting Artifacts
    • 📦Network Packet Analysis
      • The Basic
      • Tshark | Zeek Copy & Paste
      • Network Analysis Resources
    • Grep | Powershell Search | Regex
    • Hunting Resources
  • 🎵In my remains
    • Choices
    • The Art of Facing Unknown Problems
    • Build the best DFIR team
    • Reverse Engineering - Đồ án hướng ngành A "Hụt" của tôi
Powered by GitBook
On this page
  • Đồ Án Hướng ngành A
  • Dịch Ngược - Reverse Engineering
  • x86, Assembly, Stack, Call Conventions
  • x86, Assembly - Tổng quan
  • The Stack - Khái niệm
  • Calling Conventions
  • PE Format
  • Disassembler - IDA
  • Debugger - OllyDbg
  • Decompiler - Hex-Rays
  • Những Kỹ Thuật Dịch Ngược
  • Static Analysis
  • Dynamic Analysis
  • Reverse Engineering - Windows
  • Những Kỹ Thuật Chống Dịch Ngược
  • Packer/ Crypter/ Protector
  • Anti-Disassembly
  • Anti-Debugging
  • Anti-Virtual Machine
  • Refs

Was this helpful?

  1. In my remains

Reverse Engineering - Đồ án hướng ngành A "Hụt" của tôi

Sinh viên thực hiện: Nguyễn Đăng Khương

I would love to do this but the lecture who

Đồ Án Hướng ngành A

Sinh viên thực hiện: Nguyễn Đăng Khương

Đồ án hướng ngành A - Reverse Engineering được tôi nghiên cứu và biên soạn dựa trên những kiến thức có liên quan đến Dịch ngược Đồng thời, căn cứ vào nền tảng kế thừa những thành tựu của các chuyên gia đi trước trong lĩnh vực tìm hiểu (đào sâu) về Dịch ngược, cũng như áp dụng các thành tựu mà ngành CNTT đạt được vào việc phân tích, hệ thống hóa những tri thức khoa học thuộc về hướng ngành này.

Bên cạnh đó, Đồ án này được cấu trúc theo tất cả 9 phần, tuân thủ theo nguyên tắc trật tự của một bài Đồ án hoàn chỉnh. Ngoài những phần có tính phân tích kỹ lưỡng các khái niệm về dịch ngược được biên soạn và tham khảo dựa theo rất nhiều nguồn, và kiến thức cá nhân, thì Đồ án còn bổ sung và cung cấp những dẫn chứng, ví dụ cụ thể minh họa cho các lý thuyết được đề cập.

Phần

Tiêu Đề

1

Dịch Ngược - Reverse Engineering

2

x86, Assembly, Stack, Call Conventions

3

PE Format

4

Disassambler - IDA

5

Debugger - OllyDbg

6

Decompiler - Hex Ray

7

Những Kỹ Thuật Dịch Ngược

8

Những kỹ Thuật Chống Dịch Ngược

9

Refs

Đây toàn bộ đều là công sức miệt mài, nghiêm túc nghiên cứu của tôi trong suốt thời gian vừa qua. Đồ án Hướng ngành A tuy đã được cố gắng viết hoàn chỉnh nhưng chắc chắn không thể tránh khỏi các sai sót trong quá trình soạn thảo. Kính mong quý Thầy (Cô) trong quá trình hướng dẫn, phê duyệt sẽ nhiệt tình, công tâm góp ý để sản phẩm khoa học của tôi được hoàn thiện hơn.

Tôi xin chân thành cảm ơn lời đóng góp và sự đón nhận từ quý Thầy (Cô) và những người quan tâm đến Đồ án này!

Dịch Ngược - Reverse Engineering

Đây là quá trình mà phân tích, mổ xẻ một sự vật hiện tượng (cụ thể ở đây là phần mềm) để hiểu rõ cách nó được thiết kế, cách thức hoạt động của nó, làm sao nó đạt được những trạng thái như vậy và mục đích của nó là gì?

Trong trường hợp của chúng ta thì chúng ta sẽ RE phần mềm cho nên là chúng ta cần phải hiểu rõ luồng logic và instruction của Assembly, điều này nói thì dễ hơn làm, tại vì cơ bản RE là một quá trình đòi hỏi nhiều thời gian và công sức.

Mục tiêu trong RE phần mềm là hiểu cách nó hoạt động và làm thế nào nó hoạt động như vậy.

x86, Assembly, Stack, Call Conventions

Theo những kiến thức tôi đọc được từ sách và các tài liệu tham khảo đáng tin cậy, thì trước khi bắt đầu RE, chúng ta cần củng cố các kiến thức nền có liên quan đến các khái niệm sau đây

  • x86

  • Assembly

  • Stack

  • Call Conventions

x86, Assembly - Tổng quan

Để muốn có thể RE thì trước tiêng ta phải biết x86 và Assembly, Vậy tại sao chúng ta cần phải biết những thứ này? Liệu những khái niệm này có liên quan mật thiết đến RE hay không?

Nếu bạn hỏi, tất cả chương trình của bạn viết ra đều phải được dịch ra ngôn ngữ Assembly. Nói đúng hơn thì Assembly là một nhóm ngôn ngữ "class of languages" Trong các tài liệu nghiên cứu của những chuyên gia, nhà nghiên cứu đi trước họ đều đã đề cập đến những vấn đề này, tôi chính là đang thuật lại các khái niệm đã được chứng minh sẵn.

Ví dụ đây là một đoạn code C nhỏ

#include <stdio.h>

int main(void){

    printf("Hello, World!");
    return 0;
}

Sau khi được compile, link và assemble nó sẽ thành một file .exe (trong thế giới Windows) hoặc .out (nếu ở trong nền tảng Linux), nhìn cái hình dưới đây là bạn sẽ hiểu tại sao chúng ta nên biết Assembly, vì cơ bản mọi phần mềm đều dịch ra nó và nó cũng dễ đọc hơn so vói machine code và binary, nếu muốn dịch ngược thì bạn bắt buộc phải biết nó, tại vì đa số bạn sẽ được giao cho một file thực thi và phải dịch ngược nó về trạng thái High level language.

Assembly nó sẽ giống như thế này, Assembly instruction tượng trưng cho đoạn code C helloworld bên trên, dưới đây thì là intel x86

...
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
...
source: https://montcs.bloomu.edu/Information/LowLevel/Assembly/hello-asm.

Nhiệm vụ của mình trong RE là đọc Assembly và hiểu nó, bạn làm thì sau khi đọc hiểu nó thì sẽ tuỳ vào trường hợp và hoàn cảnh công việc của bạn, nếu như bạn crack phần mềm thì bạn sẽ hiểu cách nó hoạt động để lách luật, còn nếu bạn là malware analyst thì bạn sẽ hiểu để mà ngăn chặn mã độc, ...

Assembly - Kiến thức cơ bản

Tôi sẽ để một số link ở dưới phần Refs để bạn có thể tự học. Đây là những khái niệm khoa học đòi hỏi có sự nghiên cứu, suy ngẫm và liên hệ đến các khái niệm thuộc nhiều chủ đề cho nên tốt nhất người đọc cần tự trang bị các hành trang cần thiết về mặt kiến thức nền tảng.

Trước hết thì bạn nên biết về chuyển đổi các hệ cơ số, biết về lập trình (ngôn ngữ nào cũng được tuy nhiên C và C++ thì sẽ tuyệt hơn vì bạn sẽ phải làm quen với con trỏ và địa chỉ vùng nhớ, ...) những phép toán logic (AND, OR, XOR, Shift ...) và một chút về hệ thống máy tính

Đầu tiên chúng ta phải hiểu về những nstruction trong Assembly, thì cơ bản khi mà một chương trình được chạy thì nó sẽ được load lên RAM thì có những giai đoạn xảy ra như sau

  1. Những cái instruction của chương trình sẽ dc CPU đọc thông qua Control Unit

  2. Những instruction sẽ được xử lý và thực thi thông qua ALU (Arithmetic Logic unit) cùng với những input từ người dùng (Bàn phím, chuột, ...) hoặc là những Register (Thanh ghi)

  3. Sau khi mà xử lý xong thì nó sẽ một là lưu giá trị ở trên Register hoặc là xuất ra Output device (màn hình, ...)

Nếu bạn muốn biết thêm về John Von neumann và kiến trúc của ông thì đây là một số thông tin

Những instruction đó như thế nào?

Đa số những instruction này sẽ có dạng mnemonic + optional operands ví dụ như ở helloworld assembly ở ví dụ trên.

Mnemonic thì sẽ tuỳ vào loại chip, tuy nhiên chức năng có thể sẽ giống nhau, chỉ ghi khác nhau, ở intel x86 thì syntax nó như thế này, chức năng của từng mnemonic sẽ được ghi rõ trong hướng dẫn sử dụng

MOV EAX, EBX
MOV là mnemonic
EAX và EBX chính là các operand

Bạn nên google xem những instruction làm gì với operand của nó và chức năng nó là gì, hãy bắt đầu bằng với lệnh mov nhá, hãy google xem nó thực sự làm gì với EAX và EBX

Lưu ý opcodes chính là dạng byte của instruction (mnemonic và operand)

Operand thì bao gồm có

  • Immidiate (kiểu như số) vd: 0x10

  • Register (Thanh ghi) vd: EAX

  • Memory address (địa chỉ bộ nhớ) [0x0401000 + 4]

Một số instruction nổi tiếng và thường gặp. Ngoài ra, còn nhiều những instruction khác nhưng trong giới hạn cho phép của Đồ án, tôi sẽ nêu ra một vài dẫn chứng mà tôi cho là tiêu biểu, có tính thực tiễn cao như sau:

Data Storage

  • mov

  • lea

Arithmetic

  • add

  • sub

  • mul

  • div

  • inc

  • dec

Logic

  • or

  • xor

  • add

  • shr

  • shl

Stack

  • push

  • pop

  • call

  • ret

Control Flow

Cơ bản là assembly nó không có if - else gì cả và cũng chả có for loop, while loop nên cách nó có thể điều khiển flow của chương trình là bằng những flag và jump

  • jump

  • test

  • cmp

  • jcc (cái này gọi là jump khi condition is met í)

Một số khá nhiều để bạn tự tìm hiểu đấy

Register - Khái niệm

Đây là đơn vị nhỏ nhất chứa dữ liệu trong CPU cho nên là cái tốc độ truy cập dữ liệu của nó à cực kì nhanh, đây là chúng nó nhá

x86 là 32bit cho nên những register này đều là 32bit (AX, AH và AL là 16,8 bit)

Những general register thì đều tương tự nhau. Tuy nhiên, nếu mà không có Convention hay gì hết thì giai đoạn trước, code assembly sẽ rất là loạn (hỗn tạp, và khó kiểm soát, do general register đều tương tự nhau) cho nên người ta cần thiết phải đặt ra một số quy chuẩn ngầm, và nó được áp dụng cho đến ngày nay.

EAX thì dành cho giá trị trả về của hàm (giá trị return của function í)

ECX thì là counters, có nghĩa là biến trong vòng lặp í, mỗi lần lặp thì

ECX sẽ tăng lên EDX hoặc EAX cũng có thể là thương số hoặc là số dư trong phép chia và phép nhân

ESP thì dành cho stack pointer

EBP thì là base pointer

Hai khái niệm ESP và EBP sẽ chịu trách nhiệm cho việc tạo ra stack frame ở phần bên dưới mà tôi chuẩn bị phân tích dưới đây.

EIP là Instruction pointer, trỏ tới instruction tiếp theo chuẩn bị thực thi

EFLAGS dùng để thể hiện thông tin của phép toán vừa được thực hiện ở instruction trước, những cờ hiệu hay sử dụng là zero flag, sign flag, carry flag (đây là những điều kiện jump mà tôi nói ở phần Control Flow ở )

Chi tiết hơn thì có thể tìm ở đây

The Stack - Khái niệm

Như bạn thấy thì chương trình sẽ load lên RAM và CPU chủ yếu sẽ nói chuyện với RAM (như trên kiến trúc von neumann) vậy thì chương trình sẽ load những gì lên RAM?

Đa số các chương trình sẽ load những thứ gọi là "section" lên trên memory (trong windows file thực thi thì sẽ load PE lên, linux thì sẽ load ELF, ... Trong đó sẽ có những thông tin để mà cho loader có thể gọi là thực thi chương trình của bạn), nó sẽ giống giống như thế này

Hi vọng các bạn đã biết stack là gì rồi, thì ở đây bạn có thể thấy khi chương trình được load lên main memory hay còn gọi là RAM thì nó bao gồm:

  • Stack là LIFO (có nghĩa là Last in first out) là nơi mà những function những biến local được load lên

  • Heap là dynamic memory

  • Code là well dễ hiểu mà đúng không "Code", đây là instruction của bạn đấy

  • Data khởi tạo những biến tĩnh

Stack Frame - Khái Niệm

Như chúng ta đã thấy ở trên hình trên và hình dưới thì stack có fixed size và sẽ lớn lên và hướng về địa chỉ thấp nhất, tuy nhiên thì tại sao chúng có stack frame để làm gì?

Stack frame là là sự kết hợp giữa EBP và ESP, trong đó EBP sẽ là base pointer có nghĩa là trỏ tới đáy của stack còn ESP sẽ là stack pointer trỏ đến đỉnh của stack. Sẽ rất khó để dùng lời văn mà mô tả, trực quan nhất sẽ là một video clip này [video] trong video này ông ấy đã nói rõ những giai đoạn của stack và assembly khi mà một hàm được gọi sẽ như thế nào. Như hình bên trên cái bạn sẽ thấy rằng có những khái niệm như:

  • Return Address

  • Parameters

  • Saved EBP (Old EBP)

  • Local Variables

#include <stdio.h>
// Hàm add nhận 2 giá trị đó là int a và int b
int add(int a , int b){
    int sum = a + b;
    // Trả về tổng của a và b
    return sum;
}
int main(void){
    int a = 3, b = 7;
    // Hàm main gọi hàm add(a,b)
    int sum = add(a,b);
    // In ra tổng 2 số
    printf("Sum is: %d ", sum);
    return 0
}

Trong đoạn code bên dưới ta thấy rằng có hàmint add(int a, int b) , trong đó a và b chính là parameters, sum chính là local variables. Vậy còn Saved EBP (Old EBP) và Return Address nằm ở đâu?

Nếu như trong đoạn C code này thì sau khi thực thi xong hàm add(int a, int b) thì nó sẽ trả về tổng rồi thoát ra khỏi hàm đó và tiếp tục hàm printf() phải không?

Ai học lập trình cũng biết nó sẽ thực thi từ trên xuống, tuy nhiên đối với assembly thì nó không dễ như vậy, mỗi hàm có địa chỉ riêng và nằm đâu đó trên RAM (Nếu chương trình được compile ở x64 thì mọi chuyện còn khó hơn, do ASLR, PIE,… ) chúng ta sẽ phải sử dụng instruction call để nhảy tới hàm đó, mỗi hàm đó sẽ tạo ra một stack frame riêng, cũng giống như hàm main là một stack frame.

Câu hỏi tiếp theo đặt ra là làm thế nào nó quay lại stack frame cũ sau khi thực thi xong? Đó chính là Saved EBP hay còn gọi là Old EBP, sau khi hàm thực hiện xong thì stack của hàm đó sẽ pop 2 giá trị ra, đó là Saved EBP (Old EBP) và Return Address. Old EBP sẽ là EBP của người gọi hàm add(int a, int b) đó chính là hàm main() và Return Address đó chính là địa chỉ của instruction tiếp theo (có nghĩa Return Address sẽ cập nhật EIP với giá trị của instruction tiếp theo)

Vậy làm sao mà chúng ta có Return Address và Saved EBP? Đó là do trước khi gọi bất kì một hàm nào thì chúng ta phải push lên stack 2 giá trị này, như trên hình thì bạn sẽ thấy parameters của hàm sẽ push lên trước rồi tới 2 giá trị này

Chúng ta nhìn vào hình bên dưới thì sẽ thấy Caller (có thể là main hoặc một hàm khác) đang gọi hàm sum(), chúng ta có thể thấy rằng Return Address chứa địa chỉ của instruction tiếp theo đó là add ở 0x004012A1 còn EBP chứa địa chỉ của EBP aller qua lệnh các instruction push ebp, mov ebp esp (thao tác này sẽ làm cho esp trỏ đến đỉnh stack frame của hàm sum), chúng ta truy xuất một là nhờ và ESP - hoặc + offset hay dùng EBP như trên hình.

Hình này sẽ cho bạn thấy tổng quan hơn

Calling Conventions

Nhưng nãy tôi có nhắc tới Caller (người gọi hàm) thì trong phần Calling Convention này tôi sẽ nói về trạng thái của Caller và Callee (hàm được gọi) cùng với đó là sự tương tác giữa chúng.

Vẫn là câu hỏi tại sao chúng ta cần biết calling conventions?

Thứ nhất đây là một bước rất quan trọng trong việc hình thành stack frame, tại vì nó sẽ ảnh hưởng đến việc vị trí của parameter (sẽ được đẩy lên stack hay là chứa ở trong register hay là cả hai)

Thứ hai calling convention sẽ chỉ ra caller và callee rằng ai sẽ dọn dẹp sau khi hoàn thành xong nhiệm vụ của nó, ai sẽ là người dọn dẹp stack frame.

Những Calling Convention:

__cdecl

Đây gọi là C Declaration, đây là convention xuất hiện và dùng trong compiler của Microsoft đồng thời cũng được dùng trong các C compiler khác ở x86 __cdecl sẽ có những thuộc tính sau đây

  • Caller sẽ là người dọn dẹp stack

  • Caller sẽ push parameter lên stack theo thứ tự từ phải sang trái

  • Caller cũng sẽ là người pop parameter ra khỏi stack

Hình trên cho ta thấy rõ là __cdecl push từ phải qua trái và thực hiện dọn dẹp stack bằng cách add esp, 12 thông qua caller main()

x86 msvc là microsoft visual c++ compiler

__stdcall

Đây gọi là standard call , điều khác biệt ở đây đó chính là callee sẽ phải dọn dẹp stack chứ không phải là caller, nhìn như trên hình chúng ta sẽ thấy rằng main() không còn add esp, 12 nữa mà thay vào đó demo() sẽ phải ret 12

Ngoài ra stdcall phải biết rõ số parameter truyền vào mới có thể sử dụng được, một ví dụ là printf() không thể dùng convention này là do parameter truyền vào printf() nó có thể giao động cho nên printf() bắt buộc phải dùng cdecl

Theo như docs của Microsoft ghi thì cdecl sẽ cho file thực thi có size lớn hơn so với stdcall

__stdcall là call convention dùng trong win32 API

__fastcall

Đúng như tên gọi của nó. Thì nó sử dụng register EDX, ECX để chứa 2 parameter đầu tiên từ trái sang phải, những parameter còn lại sẽ được push lên stack theo thứ tự từ phải qua trái, nhìn như phía bên dưới

Và callee sẽ dọn dẹp stack

__thiscall

Đây là convention dành riêng cho C++, nó dành cho những thành viên class của C++ ở x86, dưới __thiscall thì Callee sẽ dọn dẹp stack, paramater cũng sẽ push lên stack theo thứ tự từ phải sang trái, còn pointer this sẽ được đẩy vào register ECX chứ không phải stack

PE Format

Cái chuẩn này xứng đáng có một bài viết riêng về nó, cơ bản là có rất nhiều thứ để nói về nó, tuy nhiên thì tôi sẽ cố gắng tóm gọn nó trong phần này của tôi, mặc dù có rất nhiều người chắc chắn sẽ nói về vấn đề này hay hơn và chi tiết hơn tôi rất nhiều. Nhưng không sao đây là cách tôi học bằng cách giải thích và ghi blog ra tôi sẽ nhớ lâu hơn. hi vọng mọi người thích cách diễn đạt của tôi. Dưới đây là phần chi tiết về PE Format dưới lời văn của tôi.

PE là viết tắt cho Portable Executable (không phải Physical Education đâu) ~~!

Disassembler - IDA

Đây là dụng cụ không thể nào thiếu đối với một Reverse Engineer, đây là sản phẩm được phân phối bởi HexRay, mặc dù có rất nhiều Disassembler khác tuy nhiên rất nhiều chuyên gia sử dụng IDA.

Vậy thì Disassembler là gì?

Disassembly là quá trình dịch từ machine code thành assembly, cho nên disassembler là chương trình dịch machine code thành assembly một cách tự động. IDA còn làm hơn thế nữa, nó sẽ cho bạn thấy những biểu đồ như thế này

Nó có bản free và bản trả phí, ở đây thì tôi sẽ sử dụng bản free, do bản trả phí quá mắc, tôi không có tiền mua. Ngoài ra còn rất nhiều Disassembler khác như Binary Ninja, Ghidra, Hopper, Radare2, ... hầu như chúng đều phục vụ 1 mục đích, tuy nhiên có thể sẽ sử dụng những thuật toán disassembly khác nhau. Tôi sẽ nhắc đến 2 thuật toán dùng khá nhiều trong disassembly đó là:

  • Linear Sweep Disassembly

  • Recursive Descent Disassembly (IDA)

Trong cuốn The IDA Pro book: The unofficial guide to the world's most popular disassembler đã có cho chúng ta thấy một thuật toán disassembly sẽ như thế nào và việc phát triễn một thuật toán như vậy sẽ có những khó khăn như thế nào?

Bước 1

Chúng ta phải tìm được phần chứa code (hay instruction) để có thể disassemble, thường thì những instruction sẽ hòa trộn với dữ liệu cho nên phải thuật toán phải phân biệt được 2 thứ đó. Trong trường hợp cơ bản nhất hay còn gọi là thông thường nhất đó chính là 2 dạng file nổi tiếng đó là PE (dành cho Windows) và ELF (Dành cho những hệ Unix-based) những định dạng file này thường sẽ có kiến trúc dạng cây cùng với phương thức định vị entry point (như phần PE Format ở trên có nói) của vị trị code nằm ở đâu.

Bước 2

Sau khi chúng ta tìm được vị trí bắt đầu (entry point) thì việc tiếp theo sẽ là phải đọc những giá trị ở đó, quá trình này rất phức tạp do chúng ta cần phải parse (dịch) những opcode đó sao cho đúng với assembly mnemonic. Không chỉ có thế, chúng ta cần phải biết những instruction cần bao nhiêu operand, ... và chúng ta cũng cần nên nhớ rằng mỗi hệ máy khác nhau lại có chuẩn khác nhau.

Bước 3

Sau khi mọi thứ đã được hiểu và dịch, operand và mnemonic thì chúng sẽ xuất nó ra màn hình dưới dạng assembly, chúng ta có thể chọn giữa 2 định dạng được sử dụng nhiều nhất đó là AT&T hoặc Intel.

Bước 4

Chúng tự cứ lặp đi lặp lại quá trình này với những instruction tiếp theo cho đến khi hết toàn bộ file

Tại sao chúng ta lại disassembly chương trình làm gì?

  • Phân tích mã độc

  • Phân tích những chương trình có mã nguồn đóng để tìm lỗi

  • Phân tích code do compiler tạo ra có tương thích với hiệu năng compiler và tính đúng đắn của nó không

  • Hiển thị instruction khi debug

Tôi sẽ không đi sâu vào những vấn đề này, vì nó là những chủ đề rất rộng để có thể vừa những trang giấy này, nó cần rất nhiều kinh nghiệm

Debugger - OllyDbg

Một trong những debugger nổi tiếng nhất sử dụng cho x86, nó đã tồn tại hơn 10 năm và điều hay nhất là nó miễn phí. Rất nhiều nhà nghiên cứu đã sử dụng trong quá trình phân tích mã độc và RE. Ở đây tôi sẽ không hướng dẫn cách sử dụng nó.

Ngoài ra chúng ta còn những Debugger nổi tiếng khác như WinDbg, GDB, x64dbg,...

Decompiler - Hex-Rays

Những Kỹ Thuật Dịch Ngược

Những gì tôi ghi bên trên là những điều cơ bản và còn khá là nhỏ nhắn trong một lĩnh vực rộng như thế này, thú thật tôi cũng không phải là một Reverse Engineer thần thánh gì. Tuy nhiên những điều tôi ghi dưới đây chính là những kinh nghiệm của những người đi trước tôi và là những chuyên viên bảo mật có tiếng tăm trong ngành

Tôi sẽ chia làm 3 phần đó là phân tích tĩnh (static analysis) và phân tích động (dynamic analysis) sau đó tôi sẽ nói về một số vấn đề liên quan tới dịch ngược ở hệ điều hành windows

Static Analysis

Đây sẽ thường là bước đầu tiên để thực hiện những phân tích về phần mềm, đây gọi là phân tích tĩnh. Phân tích tĩnh có nghĩa là không chạy chương trình là mà chỉ đọc hiểu luồng của chương trình qua assembly

Dynamic Analysis

Reverse Engineering - Windows

Những Kỹ Thuật Chống Dịch Ngược

Nếu như dịch ngược quá dễ dàng thì ai cũng sẽ học dịch ngược như thế không còn phần mềm nào sẽ được gọi là mã nguồn đóng cả, cho nên để làm cho cuộc đời của một Reverse Engineer khó khăn hơn và khổ sở hơn thì những lập trình viên đã phát triễn những kỹ thuật chống dịch ngược, sau đây tôi sẽ nói về một số kỹ thuật

Những kỹ thuật này không chỉ nhắm tới Reverse Engineer hay Malware Analysis mà nó còn nhắm tới những chương trình phân tích tự động để có thể đánh lừa nó nhằm vượt qua rào cản và có thể thực thi những dòng code sai trái hoặc những mục đích khác.

Packer/ Crypter/ Protector

Đây là một trong những phương pháp dễ dùng và cũng rất hiệu quả để làm tăng thời gian RE lên

Anti-Disassembly

-- Những phần này tôi sẽ nghiên cứu và viết thêm.

Anti-Debugging

Anti-Virtual Machine

Refs

PE Format

Assembly

The Stack

Calling Convention

Những Kỹ Thuật Chống Dịch Ngược

PreviousBuild the best DFIR team

Last updated 1 year ago

Was this helpful?

Tham khảo stack vs heap:

Trong quá trình RE thì việc hiểu rõ stack frame hoạt động như thế nào rất là quan trọng, thực sự thì exploitation ở những đời đầu hầu như đều liên quan tới stack (lý do tại sao thì . Phrack, không đâu có thể giải thích tốt hơn ở đây)

Nếu mục đích của Disassembler là dịch machine code thành assembly thì mục đích của decompiler là biến thành những ngôn ngữ bậc cao như C/C++ , ngoài hex-rays ra thì ta còn có snowman, capstone (cái này của một chuyên gia người Việt ),...

https://www.youtube.com/watch?v=H0xGKKpKaRE&ab_channel=MITOpenCourseWare
https://www.youtube.com/watch?v=Ml3-kVYLNr8&ab_channel=Computerphile
https://www.guru99.com/stack-vs-heap.html
http://phrack.org/issues/49/14.html
[link]
https://tech-zealots.com/malware-analysis/pe-portable-executable-structure-malwareanalysis-part-2/
https://docs.microsoft.com/en-us/archive/msdn-magazine/2002/march/insidewindows-an-in-depth-look-into-the-win32-portable-executable-file-format-part-2
http://www.pelib.com/resources/kath.txt
https://www.youtube.com/c/M9development/videos
https://flint.cs.yale.edu/cs421/papers/x86-asm/asm.html
https://www.youtube.com/user/WhatsACreel
https://malwareunicorn.org/workshops/re101.html#0
https://en.wikipedia.org/wiki/X86_calling_conventions
https://guidedhacking.com/threads/calling-conventions-and-why-you-need-to-knowthem.7302/
https://docs.microsoft.com/en-us/cpp/cpp/calling-conventions?view=msvc-160
https://www.amazon.com/Practical-Malware-Analysis-Hands-Dissecting/dp/1593272901
https://anti-reversing.com/Downloads/Anti-Reversing/The_Ultimate_Anti-Reversing_Reference.pdf
🎵
source: https://blog.malwarebytes.com/security-world/2012/09/so-you-want-to-be-amalware-analyst/
Đây là hình ảnh cái quá trình đó ở high-level và đây cũng chính là kiến trúc Von neumann
https://flint.cs.yale.edu/cs421/papers/x86-asm/asm.html
source: https://malwareunicorn.org/workshops/re101.html#0
https://www.begin.re/x86-overview
Hình tôi khi sử dụng compiler explorer
Chụp từ IDA Freeware
Page cover image