Tổng quan về kiến ​​trúc CPU

Kiến trúc CPU được sử dụng rộng rãi nhất có nguồn gốc từ kiến ​​trúc Von Neumann. Tổng quan ngắn gọn về kiến ​​trúc này được thể hiện trong sơ đồ dưới đây.

Sơ đồ này cho thấy CPU có ba thành phần: Đơn vị logic số học (ALU), Đơn vị điều khiển và Thanh ghi. CPU tương tác với bộ nhớ và các thiết bị I/O bên ngoài CPU. Hãy cùng tìm hiểu về từng thành phần được đề cập trong sơ đồ dưới đây.

  • Control Unit: Thiết bị Điều khiển nhận lệnh từ bộ nhớ chính, được mô tả ở đây bên ngoài CPU. Địa chỉ của lệnh tiếp theo sẽ thực thi được lưu trong một thanh ghi gọi là Con trỏ lệnh hoặc IP. Trong hệ thống 32 bit, thanh ghi này được gọi là EIP và trong hệ thống 64 bit, nó được gọi là RIP.
  • Arithmetic Logic Unit: Đơn vị logic số học thực hiện lệnh được lấy từ Bộ nhớ. Kết quả của lệnh đã thực hiện sau đó được lưu trữ trong Thanh ghi hoặc Bộ nhớ.
  • Registers: Các thanh ghi là nơi lưu trữ của CPU. Các thanh ghi thường nhỏ hơn nhiều so với Bộ nhớ chính, nằm ngoài CPU và giúp tiết kiệm thời gian thực hiện các lệnh bằng cách đặt dữ liệu quan trọng vào quyền truy cập trực tiếp vào CPU.
  • Memory: Bộ nhớ, còn được gọi là Bộ nhớ chính hoặc Bộ nhớ truy cập ngẫu nhiên (RAM), chứa tất cả mã và dữ liệu để chương trình chạy. Khi người dùng thực thi một chương trình, mã và dữ liệu của nó sẽ được tải vào Bộ nhớ, từ đó CPU truy cập vào nó theo từng lệnh một.
  • I/O devices: Thiết bị I/O hoặc thiết bị Đầu vào/Đầu ra là tất cả các thiết bị khác tương tác với máy tính. Các thiết bị này bao gồm Bàn phím, Chuột, Màn hình, Máy in, Thiết bị lưu trữ dung lượng lớn như Đĩa cứng và USB, v.v.

Nói tóm lại, khi một chương trình được thực thi, nó sẽ được tải vào bộ nhớ. Từ đó, Đơn vị Điều khiển tìm nạp từng lệnh một bằng cách sử dụng Thanh ghi Con trỏ Lệnh và Đơn vị Logic Số học thực thi lệnh đó. Kết quả được lưu trữ trong Sổ đăng ký hoặc Bộ nhớ.

Tổng quan về Thanh ghi

Các thanh ghi là phương tiện lưu trữ của CPU. CPU có thể truy cập dữ liệu từ các thanh ghi nhanh hơn bất kỳ phương tiện lưu trữ nào khác; tuy nhiên, kích thước hạn chế của nó có nghĩa là nó phải được sử dụng một cách hiệu quả. Với mục đích này, các thanh ghi được chia thành các loại khác nhau sau:

  • Instruction Pointer
  • General Purpose Registers
  • Status Flag Registers
  • Segment Registers

Chúng ta hãy lần lượt đi qua từng thanh ghi dưới đây:

The Instruction Pointer

Con trỏ lệnh là một thanh ghi chứa địa chỉ của lệnh tiếp theo sẽ được CPU thực thi. Nó còn được gọi là Bộ đếm chương trình. Ban đầu nó là một thanh ghi 16 bit trong bộ xử lý Intel 8086 (từ đó thuật ngữ x86 bắt nguồn) và được viết tắt là IP. Trong bộ xử lý 32 bit, Con trỏ lệnh trở thành thanh ghi 32 bit được gọi là EIP hoặc Con trỏ lệnh mở rộng. Trong hệ thống 64 bit, thanh ghi này trở thành thanh ghi 64 bit được gọi là RIP (chữ R ở đây là viết tắt của thanh ghi).

General-Purpose Registers

Các thanh ghi đa năng trong hệ thống x86 đều là các thanh ghi 32 bit. Như tên cho thấy, chúng được sử dụng trong quá trình thực hiện chung các lệnh của CPU. Trong hệ thống 64 bit, các thanh ghi này được mở rộng thành các thanh ghi 64 bit. Chúng chứa các thanh ghi sau.

  • EAX hoặc RAX: Đây là Accumulator Register. Kết quả của các phép tính số học thường được lưu trữ trong thanh ghi này. Trong hệ thống 32 bit, có thanh ghi EAX 32 bit, trong khi thanh ghi RAX 64 bit có trong hệ thống 64 bit. 16 bit cuối cùng của thanh ghi này có thể được truy cập bằng địa chỉ AX. Tương tự, nó cũng có thể được xử lý bằng 8 bit bằng cách sử dụng AL cho 8 bit thấp hơn và AH cho 8 bit cao hơn.
  • EBX hoặc RBX: Thanh ghi này còn được gọi là Base Register, thường được sử dụng để lưu trữ địa chỉ cơ sở để tham chiếu một offset. Tương tự như EAX/RAX, nó có thể được đánh địa chỉ dưới dạng các thanh ghi RBX 64 bit, EBX 32 bit, BX 16 bit và các thanh ghi BH và BL 8 bit.
  • ECX hoặc RCX: Thanh ghi này còn được gọi là Counter Register và thường được sử dụng trong các hoạt động đếm như vòng lặp, v.v. Tương tự như hai thanh ghi trên, nó có thể được đánh địa chỉ là RCX 64 bit, ECX 32 bit, CX 16 bit và 8 -bit thanh ghi CH và CL.
  • EDX hoặc RDX: Thanh ghi này còn được gọi là Data Register. Nó thường được sử dụng trong các phép tính nhân/chia. Tương tự như các thanh ghi trên, nó có thể được định địa chỉ là các thanh ghi RDX 64 bit, EDX 32 bit, DX 16 bit và 8 bit DH và DL.
  • ESP hoặc RSP: Thanh ghi này được gọi là Stack Pointer. Nó trỏ đến đỉnh ngăn xếp và được sử dụng cùng với thanh ghi Phân đoạn ngăn xếp. Đó là thanh ghi 32 bit được gọi là ESP trong hệ thống 32 bit và thanh ghi 64 bit được gọi là RSP trong hệ thống 64 bit. Nó không thể được giải quyết như các thanh ghi nhỏ hơn.
  • EBP hoặc RBP: Thanh ghi này được gọi là Base Pointer. Nó được sử dụng để truy cập các tham số được truyền bởi ngăn xếp. Nó cũng được sử dụng cùng với thanh ghi Phân đoạn ngăn xếp. Đó là thanh ghi 32 bit được gọi là EBP trong hệ thống 32 bit và thanh ghi 64 bit được gọi là RBP trong hệ thống 64 bit.
  • ESI hoặc RSI: Thanh ghi này được gọi là thanh ghi Source Index. Nó được sử dụng cho các hoạt động chuỗi. Nó được sử dụng với thanh ghi Phân đoạn dữ liệu (DS) làm phần bù. Đó là thanh ghi 32 bit được gọi là ESI trong hệ thống 32 bit và thanh ghi 64 bit được gọi là RSI trong hệ thống 64 bit.
  • EDI hoặc RDI: Thanh ghi này được gọi là thanh ghi Destination Index. Nó cũng được sử dụng cho các hoạt động chuỗi. Nó được sử dụng với thanh ghi Phân đoạn bổ sung (ES) làm phần bù. Đó là thanh ghi 32 bit được gọi là EDI trong hệ thống 32 bit và thanh ghi 64 bit được gọi là RDI trong hệ thống 64 bit.
  • R8-R15: Các thanh ghi đa năng 64 bit này không có trong hệ thống 32 bit. Chúng đã được giới thiệu trong hệ thống 64-bit. Chúng cũng có thể định địa chỉ ở các chế độ 32 bit, 16 bit và 8 bit. Ví dụ: đối với thanh ghi R8, chúng ta có thể sử dụng R8D cho địa chỉ 32 bit thấp hơn, R8W cho địa chỉ 16 bit thấp hơn và R8B cho địa chỉ 8 bit thấp hơn. Ở đây, hậu tố D là viết tắt của Double-word, W là viết tắt của Word và B là viết tắt của Byte.

Status Flag Registers

Khi thực hiện việc thực thi, đôi khi cần có một số dấu hiệu về trạng thái thực thi. Đây là lúc Cờ trạng thái xuất hiện. Đây là một thanh ghi 32 bit duy nhất cho hệ thống 32 bit có tên là EFLAGS, được mở rộng thành 64 bit cho hệ thống 64 bit và được gọi là RFLAGS trong hệ thống 64 bit. Thanh ghi cờ trạng thái bao gồm các cờ bit đơn riêng lẻ có thể là 1 hoặc 0. Một số cờ cần thiết được thảo luận dưới đây:

  • Zero Flag: Ký hiệu là ZF, Cờ Zero cho biết khi nào kết quả của lệnh được thực hiện cuối cùng bằng 0. Ví dụ: nếu một lệnh được thực thi trừ RAX khỏi chính nó thì kết quả sẽ là 0. Trong tình huống này, ZF sẽ được đặt thành 1.
  • Carry Flag: Ký hiệu là CF, Cờ nhớ cho biết khi nào lệnh được thực hiện cuối cùng dẫn đến một số quá lớn hoặc quá nhỏ so với đích. Ví dụ: nếu chúng ta thêm 0xFFFFFFFF và 0x00000001 và lưu kết quả vào thanh ghi 64 bit, kết quả sẽ quá lớn đối với thanh ghi. Trong trường hợp này, CF sẽ được đặt thành 1.
  • Sign Flag: Cờ dấu hoặc SF cho biết kết quả của phép toán là âm hay bit quan trọng nhất được đặt thành 1. Nếu các điều kiện này được đáp ứng, SF được đặt thành 1; nếu không, nó được đặt thành 0.
  • Trap Flag: Cờ bẫy hoặc TF cho biết bộ xử lý có ở chế độ gỡ lỗi hay không. Khi TF được thiết lập, CPU sẽ thực thi từng lệnh một cho mục đích gỡ lỗi. Điều này có thể được phần mềm độc hại sử dụng để xác định xem chúng có đang được chạy trong trình gỡ lỗi hay không.
General RegistersSegment RegistersStatus RegistersInstruction Pointer
RAX, EAX, AX, AH, ALCSEFLAGSEIP, RIP
RBX, EBX, BX, BH, BLSS
RCX, ECX, CX, CH, CLDS
RDX, EDX, DX, DH, DLES
RBP, EBP, BPFS
RSP, ESP, SPGS
RSI, ESI, SI
RDI, EDI, DI
R8-R15

Segment Registers

Các thanh ghi phân đoạn là các thanh ghi 16 bit chuyển đổi không gian bộ nhớ phẳng thành các phân đoạn khác nhau để đánh địa chỉ dễ dàng hơn. Có sáu thanh ghi phân đoạn, như được giải thích dưới đây:

  • Code Segment: (CS) thanh ghi trỏ tới phần Code trong bộ nhớ.
  • Data Segment: (DS) thanh ghi trỏ tới phần dữ liệu của chương trình trong bộ nhớ.
  • Stack Segment: (SS) thanh ghi trỏ tới Stack của chương trình trong bộ nhớ.
  • Extra Segments (ES, FS, and GS): Các thanh ghi phân đoạn bổ sung này trỏ đến các phần dữ liệu khác nhau. Những phần này và thanh ghi DS chia bộ nhớ của chương trình thành bốn phần dữ liệu riêng biệt.

Tổng quan về bộ nhớ

Khi một chương trình được tải vào Bộ nhớ trong Hệ điều hành Windows, nó sẽ nhìn thấy chế độ xem trừu tượng của Bộ nhớ. Điều này có nghĩa là chương trình không có quyền truy cập vào toàn bộ Bộ nhớ; thay vào đó, nó chỉ có quyền truy cập vào Bộ nhớ của nó. Đối với chương trình đó, đó là tất cả Bộ nhớ mà nó cần. Để cho ngắn gọn, chúng ta sẽ không đi sâu vào chi tiết về cách Hệ điều hành thực hiện việc trừu tượng hóa. Chúng tôi sẽ xem xét Bộ nhớ như một chương trình nhìn thấy nó, vì điều đó phù hợp hơn với chúng tôi khi thiết kế ngược phần mềm độc hại.

Sơ đồ ở đây là tổng quan về cách bố trí bộ nhớ điển hình cho một chương trình. Có thể thấy, Memory được chia thành nhiều phần khác nhau là Stack, Heap, Code và Data. Mặc dù chúng tôi đã hiển thị bốn phần theo một thứ tự cụ thể, nhưng điều này có thể khác với cách chúng thường diễn ra, ví dụ: phần Mã có thể nằm bên dưới phần Dữ liệu.

  • Code: Phần Code, đúng như tên gọi, chứa mã của chương trình. Cụ thể, phần này đề cập đến phần văn bản trong tệp Thực thi di động, bao gồm các hướng dẫn được CPU thực thi. Phần này của Bộ nhớ có quyền thực thi, nghĩa là CPU có thể thực thi dữ liệu trong phần này của bộ nhớ chương trình.
  • Data: Phần Data chứa dữ liệu khởi tạo không thay đổi và không đổi. Nó đề cập đến phần dữ liệu trong một tệp có thể thực thi được. Nó thường chứa các biến Toàn cục và các dữ liệu khác không được phép thay đổi trong quá trình thực thi chương trình.
  • Heap: Heap, còn được gọi là Bộ nhớ động, chứa các biến và dữ liệu được tạo và hủy trong quá trình thực thi chương trình. Khi một biến được tạo, bộ nhớ sẽ được cấp phát cho biến đó trong thời gian chạy. Và khi biến đó bị xóa, bộ nhớ sẽ được giải phóng. Do đó có tên bộ nhớ động.
  • Stack: Ngăn xếp là một trong những phần quan trọng của Bộ nhớ theo quan điểm phân tích phần mềm độc hại. Phần này của Bộ nhớ chứa các biến cục bộ, các đối số được truyền cho chương trình và địa chỉ trả về của tiến trình cha đã gọi chương trình. Do địa chỉ trả về có liên quan đến luồng điều khiển của các lệnh của CPU nên ngăn xếp thường bị phần mềm độc hại nhắm tới để chiếm đoạt luồng điều khiển.

Bố cục ngăn xếp

Ngăn xếp là một phần bộ nhớ của chương trình chứa các đối số được truyền cho chương trình, các biến cục bộ và luồng điều khiển của chương trình. Điều này làm cho ngăn xếp trở nên rất quan trọng đối với việc phân tích phần mềm độc hại và kỹ thuật đảo ngược. Phần mềm độc hại thường khai thác ngăn xếp để chiếm đoạt luồng điều khiển của chương trình. Vì vậy, điều quan trọng là phải hiểu ngăn xếp, cách bố trí và hoạt động của nó.

Ngăn xếp là bộ nhớ Last in First out (LIFO). Điều này có nghĩa là phần tử cuối cùng được đẩy lên ngăn xếp là phần tử đầu tiên được bật ra. Ví dụ: nếu chúng ta đẩy A, B và C vào ngăn xếp, khi chúng ta lấy ra các phần tử này, phần tử đầu tiên bật ra sẽ là C, B, rồi đến A. CPU sử dụng hai thanh ghi để theo dõi ngăn xếp. Một là Con trỏ ngăn xếp (ESP hoặc RSP) và cái còn lại là Con trỏ cơ sở (EBP hoặc RBP).

  • The Stack Pointer: Con trỏ ngăn xếp trỏ đến đỉnh ngăn xếp. Khi bất kỳ phần tử mới nào được đẩy vào ngăn xếp, vị trí của Con trỏ ngăn xếp sẽ thay đổi để xem xét phần tử mới được đẩy vào ngăn xếp. Tương tự, khi một phần tử được đưa ra khỏi ngăn xếp, con trỏ ngăn xếp sẽ tự điều chỉnh để phản ánh sự thay đổi đó.
  • The Base Pointer: Con trỏ cơ sở cho bất kỳ chương trình nào vẫn không đổi. Đây là địa chỉ tham chiếu nơi ngăn xếp chương trình hiện tại theo dõi các biến và đối số cục bộ của nó.
  • Old Base Pointer and Return Address: Bên dưới Con trỏ cơ sở là Con trỏ cơ sở cũ của chương trình gọi (chương trình gọi chương trình hiện tại). Và bên dưới Con trỏ cơ sở cũ là Địa chỉ trả về, nơi Con trỏ lệnh sẽ trả về sau khi quá trình thực thi chương trình hiện tại kết thúc. Một kỹ thuật phổ biến để chiếm quyền điều khiển luồng là tràn một biến cục bộ trên ngăn xếp sao cho nó ghi đè Địa chỉ trả về bằng địa chỉ do tác giả phần mềm độc hại lựa chọn. Kỹ thuật này được gọi là Tràn bộ đệm ngăn xếp.
  • Arguments: Các đối số được truyền cho một hàm sẽ được đẩy vào ngăn xếp trước khi hàm bắt đầu thực thi. Các đối số này hiện diện ngay bên dưới Địa chỉ trả về trên ngăn xếp.
  • Function Prologue and Epilogue: Khi một hàm được gọi, ngăn xếp được chuẩn bị để hàm thực thi. Điều này có nghĩa là các đối số được đẩy vào ngăn xếp trước khi bắt đầu thực thi hàm. Sau đó, Địa chỉ trả về và Con trỏ cơ sở cũ được đẩy vào ngăn xếp. Khi các phần tử này được đẩy, địa chỉ Con trỏ cơ sở sẽ được thay đổi thành đầu ngăn xếp (lúc đó sẽ là Con trỏ ngăn xếp của hàm người gọi). Khi hàm thực thi, Con trỏ ngăn xếp sẽ di chuyển theo yêu cầu của hàm. Phần mã này đẩy các đối số, Địa chỉ trả về và Con trỏ cơ sở vào Ngăn xếp và sắp xếp lại Ngăn xếp và Con trỏ cơ sở được gọi là Lời mở đầu hàm.

Leave a Reply

This site uses cookies to offer you a better browsing experience. By browsing this website, you agree to our use of cookies.