2009-08-18 44 views
6

xem xét mã này lắp ráp x86:dereferencing một nhãn trong x86 lắp ráp

section .data 

foo: 
    mov ebx, [boo] 
    mov [goo], ebx 
goo: 
    mov eax, 2 
    mov eax, 3 
    ret 
boo: 
    mov eax, 4 
    mov eax, 5 
    ret 

gì chính xác là xảy ra ở đây? Khi tôi dereference [boo]mov nó đến [goo] chính xác thì tôi di chuyển ở đó? Chỉ một mệnh lệnh? Các ret là tốt?


câu hỏi Follow-up:

  1. Liệu dereferencing một nhãn cho tôi một địa chỉ? Hoặc mã máy cho lệnh đầu tiên trong nhãn?
  2. Nếu đó là mã máy - làm cách nào có thể có nhiều hơn một lệnh? Không phải tất cả các lệnh cơ bản là 32-bit (ngay cả khi không phải tất cả các bit đều được sử dụng)?
  3. Tóm tắt - sẽ eax có giá trị 3 hoặc 5 ở cuối không?

Trả lời

9

boo được bù đắp của hướng dẫn mov eax, 3 bên trong phần .data. mov ebx, [boo] có nghĩa là "lấy bốn byte tại khoảng bù được chỉ định bởi boo bên trong ebx". Tương tự, mov [goo], ebx sẽ di chuyển nội dung của ebx tại độ lệch được chỉ định bởi goo.

Tuy nhiên, mã thường chỉ đọc, vì vậy sẽ không ngạc nhiên khi thấy mã chỉ bị lỗi.

Sau đây là cách hướng dẫn tại boo được mã hóa:

boo: 
b8 03 00 00 00   mov eax,0x3 
c3      ret 

Vì vậy, những gì bạn nhận được trong ebx thực sự là 4/5 của lệnh mov eax, 3.

+1

Dường như điều này xảy ra để làm việc vì họ không đầy đủ 32-bit với số lượng và byte cuối cùng sẽ luôn là 0. Mã này sẽ thất bại nếu bạn thử một cái gì đó như mov, eax 0xC000000 – Michael

+0

"lấy bốn byte" là những gì tôi đang tìm kiếm. cảm ơn! –

3

Bản ghi đầu tiên được sao chép từ goo bù trừ tương ứng với thanh ghi phân đoạn [e] DS. Các mov thứ hai là viết tại offset của foo vào một vị trí dữ liệu liên quan đến đăng ký DS. Nếu CS và DS là trùng hợp, thì điều này có thể bị bỏ qua. Giả sử CS và DS là trùng hợp ngẫu nhiên, bạn tiếp theo có khả năng chạy vào các cơ chế bảo vệ khác nhau để hiển thị các phần mã chỉ đọc.

RE followups:

  1. Một isnt nhãn như một tài liệu tham khảo - bạn không dereference như vậy. Bộ lắp ráp thay thế bằng một số đại diện cho vị trí trong mã kết quả. Bạn có thể tải địa chỉ hoặc địa chỉ tại địa chỉ. Các [và] chỉ dereferencing - Tôi đã cố định một yếu tố khó hiểu trong phản ứng đầu tiên của tôi để trang trải này. IOW làm [goo] tải thứ ở địa chỉ đó.
  2. Lệnh hướng dẫn CISC như x86 có [rất] hướng dẫn độ dài thay đổi - một số thậm chí không phải là bội số của độ dài từ. RISC thường cố gắng để rstict này để làm cho các hướng dẫn giải mã đơn giản hơn.
  3. 3 - bạn chỉ sửa đổi 4 byte đầu tiên của mov eax, 2 (trong đó, do mã hóa cuối ít được thay thế bằng 4 nhưng sau đó bị ghi đè bởi lệnh kế tiếp chưa được sửa đổi chút nào - 5 không bao giờ trong hình ảnh như một ứng cử viên (tôi nghĩ rằng bạn đã suy nghĩ mã được sắp xếp lại theo cách bạn đặt câu hỏi đầu tiên [1] mặc dù bạn biết rõ hơn một chút như tôi đã đoán từ đại diện của bạn: P)]).

Lưu ý rằng tất cả điều này giả định rằng CS = DS và DEP isnt bước vào.

Ngoài ra, nếu bạn đang sử dụng BX thay vì EBX, các loại điều bạn đang mong đợi sẽ đi vào chơi (sử dụng xX thay vì ExX truy cập 2 byte thấp của thanh ghi [và xL truy cập byte thấp nhất])

[1] Hãy nhớ rằng một bộ hoàn toàn là công cụ để viết opcodes - thứ như nhãn vv. số vv với rất ít ma thuật hoặc sự biến đổi ấn tượng của mã - không có đóng cửa hay bất kỳ thứ gì sâu thẳm của thiên nhiên ẩn giấu trong đó. (Điều này là hơi quá đơn giản - mã có thể được định vị, và trong nhiều trường hợp fixups được áp dụng đối với tập quán của offsets bởi sự kết hợp của các mối liên kết và các bộ nạp)

+0

đúng - Tôi đã có RISC trong tâm trí ... thanks for thanh toán bù trừ lên rằng điểm –

2

Theo dõi câu trả lời:

  1. Nó cung cấp cho bạn mã máy bắt đầu từ địa chỉ. Bao nhiêu trong đó phụ thuộc vào độ dài của tải của bạn, trong trường hợp này nó là 4 byte.

  2. Có thể có nhiều lệnh hoặc chỉ một đoạn lệnh. Trên các lệnh máy mã kiến ​​trúc (Intel x86) có từ 8 đến 120 bit.

  3. 3.

Các vấn đề liên quan