1. Các thanh ghi 32 bit
1. Nhóm các thanh ghi công dụng chung:
a. 8 Thanh ghi đa năng 32 bit: EAX, EBX, ECX, EDX, ESI, EDI, DBP, ESP dùng để
lưu trữ tham số của các phép tính, tham số của các phép tính địa chỉ, và con trỏ
bộ nhớ (bên ngoài), thanh ghi ESP đặc biệt chỉ dùng làm con trỏ ngăn xếp.
b. 6 thanh ghi đoạn 16 bit: CS, DS, SS, ES, FS, GS dùng để lưu trữ bộ chọn đoạn
để quản lý bộ nhớ trong mô hình phẳng hoặc phân đoạn.
c. Thanh ghi cờ EFLAGS 32 bit dùng để giám sát 32 trạng thái của dử liệu đang
tính toán trong các thanh ghi nói trên
d. Thanh ghi con trỏ lệnh EIP dùng để lưu địa chỉ lệch của mã lệnh sắp tiến hành.
thanh ghi này hầu như không cho phép truy cập, nếu muốn thì chỉ có thể dung
lệnh call để đọc giá trị của con trỏ lệnh từ ngăn xếp.
e. 4 thanh ghi quản lý bộ nhớ 48 Bit đó là: GDTR, LDTR, IDTR dùng để quản lý bộ
nhớ (ram)
f. 1 thanh ghi nhiệm vụ 64 bit dùng để điều khiển các chức năng đặc biệt khi hệ
điều hành thay đổi cách quản lý bộ nhớ (ví dụ hệ điều hành dos thì quản lý bộ
nhớ theo kiểu thực còn windows thì quản lý theo kiểu phân trang, bảo vệ...)
g. 5 thanh ghi điều khiển 32 bit: CR0, CR1, CR2, CR3, CR4
h. 8 thanh ghi 32 bit từ DR0 --DR7 debug dùng để kiểm tra quá trình debug bên
trong vi xử lý.
2. Nhóm các thanh ghi tạm
đây là các thanh ghi trung gian từ 32 bit cho đến 127 bit, trong quá trình vi xử lý
tiếp nhận mã lệnh từ tiểu hệ bộ nhớ L1, nó sẽ chia nhỏ cái lệnh đó ra thành nhiều
vi lệnh rồi chuyển giao cho các bộ ALU tính toán, hoặc nếu có tính toán số thực
thì nó sẻ chuyển giao cho bộ đồng xử lý toán học giải quyết, sau khi tính toán nó
sẽ tổng kết số liệu lại rồi trả kết quả, đây là mô hình siêu đường ống cực kỳ phức
tạp.
--------------
Chi tiết
Nhắc lại kiến thức cũ về các thanh ghi 16bit
Khi 1 chương trình được nạp vào bộ nhớ thì nó bao gồm các phần sau đây:
code:chứa các mã lệnh,nó được nạp vào 1 phần của bộ nhớ tại 1 khoảng không
gian vật lý riêng,phần này là code segment
data:chứa các dữ liệu của chương trình và các dữ liệu phát sinh,nó nạp vào data
segment
stack: chứa địa chỉ quay về,cất và phục hồi các thanh ghi,nằm ở stack segment
Để quản lý bộ nhớ thì có kỹ thuật phân trang(paging) hoặc phân
đoạn(segmentation).
Phân đoạn thì như trên đã nêu.các segment được chia ra và đặt "lung tung" trên
bộ nhớ,hệ điều hành quản lý bằng cách tạo ra danh sách quản lý các vùng còn
trống trên bộ nhớ
Trong mỗi segment cũng chia ra những phần nhỏ,ví dụ như code segment chẳn
hạn chứa 1 dãy liên tục các lệnh liên tục nhau thì vị trí từng lệnh cũng được đánh
dấu,đó là địa chỉ offset
--
Các thanh ghi phân đoạn(segment) sẽ làm nhiệm vụ đánh dấu địa chỉ của nơi bắt
đầu các segment trên bộ nhớ
trong đoạn data segment:
SI : trỏ đến dữ liệu nguồn
DI : trỏ đến dữ liệu đích
2. BX :chỉ số nền
DX : chỉ đến dữ liệu được hiển thị
DS : trỏ đến vị trí bắt đầu data segment
trong đoạn code segment :
IP : trỏ đến lệnh kế tiếp được thực hiện
CS : trỏ đến đầu code segment
trong đoạn Stack Segment :
SP : trỏ đến đỉnh stack
BP : độ dời so với đỉnh
SS : trỏ đến đáy stack segment
----
Các thanh ghi 32 bit
Có thêm các thanh ghi mở rộng tên gọi mở rộng từ nhựng tên cũ
gồm các thanh ghi EAX EBX ECX EDX ESI EDI ESP EBP ...
3. Thanh ghi EAX EBX ECX EDX :
Các thanh ghi này cũng có chức năng tương tự các thanh ghi AX BX CX DX
Tuy nhiên trong vì đây là các thanh ghi 32bit nên ta cũng có thể sử dụng các
thanh ghi trong đó như là các thanh ghi
8bit 16bit 32bit tùy ý như EAX(32bit) AX(16bit) AH(8bit) AL(8bit)
CÔng dụng :
EAX : Dùng cho các phép toán,logic,chuyển dữ liệu
EBX : Dùng để lưu giữ địa chỉ
ECX : Dùng làm bộ đếm các vòng lặp
EDX : Dùng phối hợp EAX trong phép nhân chia ...
thanh ghi EIP : thanh ghi con trỏ lệnh.đây là thanh ghi rất quan trọng.nó sẽ trỏ
đến vị trí của lệnh kế tiếp khi
1 lệnh đuơc thực thi.Vì thế nó là 1 thanh ghi đặc biệt mà nó sẽ không tham gia
vào các lệnh như là 1 toán hạng được
4. thanh ghi ESI và EDI : các thanh ghi chỉ mục(index).Hay sử dụng trong chuỗi
hoặc mảng
Thanh ghi ESP : trỏ đến đầu stack.stack là 1 vùng trong bộ nhớ chứa các biến
tạm thời,các dữ liệu và địa chỉ.
Stack làm việc theo nguyên tắc LIFO(last in first out).
Thanh ghi EBP : là 1 thanh ghi dùng trong việc truy xuất dữ liệu trong stack.Công
dụng EBP còn trong việc lưu trữ vị
trí lệnh tiếp theo khi ứng dụng thực hiện lệnh CALL để gọi hàm(chương trình
ccon).để return lại lệnh kế tiếp.
Các thanh ghi cờ :
Gồm thanh ghi cờ trạng thái và thanh ghi cờ điều khiển.Các cờ hay dùng trong
các phép tính,điều kiện thực hiện các
phép nhảy
CF : ON khi cộng có nhớ,trừ có mượn ở bit cao
AF : ON khi có mượn hay có nhớ ở bit3
SF : ON khi phép tính có bit cao nhất âm
OF : ON khi phép tính có dấu sai.nêu cộng 2 số cùng dấu mà kết quả có dấu
ngược
thì có tràn xảy ra.Khi ta cộng hai sô khác dấu thì không bao giờ có tràn
PF : ON khi 8bit thấp là số chẵn
ZF : ON khi phép toán trả về giá trị 0
Ví dụ:
nhảy JNE nếu ZF = 0 chẵn hạn
EAX có giá trị 00000200
ECX có giá trị 00000100
thì nếu :
Code:
CMP EAX,ECX
JNE SHORT 00000301
Sau đây là bảng các lệnh nhảy có điều kiện :
x86 memory segmentation :
4 thanh ghi segment quen thuộc trong 16bit là CS DS ES và SS được gán giá trị 0
và giới hạn của bộ nhớ đến 4Gb.
Thanh ghi FS
Trong x86 trên windowns các thanh ghi FS dùng để trỏ đến các cấu trúc dự liệu
nhỏ,các luồng ....
Cụ thể hơn :
Trên win32 ,khi một ứng dụng được chạy.thì nó sinh ra 1 process,process sẽ do
Process Environment Block(PEB) quản lý.
MỘt process có thể có 1 luồng(thread) hoặc nhiều luồng nhưng ít nhất phải có 1
luồng.các luồng này do
Thread Information Block(TIB) quản lý.
Ta có thể dùng FS để truy xuất đến vùng này
5. Ta có bảng địa chỉ sau để truy xuất vào TIB
Contents of the TIB
Position Length Windows Versions Description
FS:[0x00] 4 Win9x and NT Current Structured Exception Handling (SEH) frame
FS:[0x04] 4 Win9x and NT Top of stack
FS:[0x08] 4 Win9x and NT Current bottom of stack
FS:[0x0C] 4 Unknown - TIB Subsystem?
FS:[0x10] 4 NT Fiber data
FS:[0x14] 4 Win9x and NT Arbitrary data slot
FS:[0x18] 4 Win9x and NT Linear address of TIB
---- End of NT subsystem independent part ----
FS:[0x1C] 4 NT Environment Pointer
FS:[0x20] 4 NT Process ID
FS:[0x24] 4 NT Current thread ID
FS:[0x28] 4 NT Active RPC Handle
FS:[0x2C] 4 Win9x and NT Linear address of the thread-local storage array
FS:[0x30] 4 NT Linear address of Process Environment Block (PEB)
FS:[0x34] 4 NT Last error number
FS:[0x38] 4 NT Count of owned critical sections
FS:[0x3C] 4 NT Address of CSR Client Thread
FS:[0x40] 4 NT Win32 Thread Information
FS:[0x44] 124 NT, Wine Win32 client information (NT), user32 private data
(Wine), 0x60 = LastError (Win95), 0x74 = LastError (WinME)
FS:[0xC0] 4 NT Reserved for Wow32
FS:[0xC4] 4 NT Current Locale
FS:[0xC8] 4 NT FP Software Status Register
FS:[0xCC] 216 NT, Wine Reserved for OS (NT), kernel32 private data (Wine)
FS:[0x124] 4 NT Pointer to KTHREAD (ETHREAD) structure
FS:[0x1A4] 4 NT Exception code
FS:[0x1A8] 18 NT Activation context stack
FS:[0x1BC] 24 NT, Wine Spare bytes (NT), ntdll private data (Wine)
FS:[0x1D4] 40 NT, Wine Reserved for OS (NT), ntdll private data (Wine)
FS:[0x1FC] 1248 NT, Wine GDI TEB Batch (OS), vm86 private data (Wine)
FS:[0x6DC] 4 NT GDI Region
FS:[0x6E0] 4 NT GDI Pen
FS:[0x6E4] 4 NT GDI Brush
FS:[0x6E8] 4 NT Real Process ID
FS:[0x6EC] 4 NT Real Thread ID
FS:[0x6F0] 4 NT GDI cached process handle
FS:[0x6F4] 4 NT GDI client process ID (PID)
FS:[0x6F8] 4 NT GDI client thread ID (TID)
FS:[0x6FC] 4 NT GDI thread locale information
FS:[0x700] 20 NT Reserved for user application
FS:[0x714] 1248 NT Reserved for GL
FS:[0xBF4] 4 NT Last Status Value
FS:[0xBF8] 532 NT Static UNICODE_STRING buffer
FS:[0xE0C] 4 NT Pointer to deallocation stack
FS:[0xE10] 256 NT TLS slots, 4 byte per slot
FS:[0xF10] 8 NT TLS links (LIST_ENTRY structure)
FS:[0xF18] 4 NT VDM
FS:[0xF1C] 4 NT Reserved for RPC
FS:[0xF28] 4 NT Thread error mode (RtlSetThreadErrorMode)
Nhìn vào bảng trên,ta hoàn toàn có thể truy xuất luôn đến cả PEB tại vị trí FS:
[0x30]
và FS:[0x18] sẽ là địa chỉ của TIB
6. Có 1 bài viết về PEB và TIB tại đây,có cả ví dụ rõ ràng,các bạn có thể tham khảo
thêm:
http://rootb1ez.wordpress.com/2009/12/17...structure/
Thanh ghi GS : Có cách hoạt động tương tự như với FS,GS cũng tham chiếu đến 1
số vùng nhớ đặc trưng khi 1 process chạy.Ở các dòng 64bit FS được thay thế
bằng GS
Nguồn :
http://msdn.microsoft.com/en-
us/magazine/cc300794.aspx
On x64 versions of Windows, the FS register has been replaced by the GS
register. Otherwise they work pretty much in the same manner.
Các thanh ghi khác :
Control register :
Bao gồm các thanh ghi Cr0 cr1 cr2 cr3
Chức năng của chúng chủ yếu để điều khiển quá trình hoạt động của vl,thực hiện
quá trình phân trang(paging),điều khiển ngắt ...
Chi tiết :
CR0
Cr0 dài 32 bit.Chức năng của nó nằm ở các bit quy định trên thanh ghi,cụ thể như
sau :
Nhìn trên ta có thể thấy bit 0 thể hiện chế độ Protected Mode nếu mang giá trị 1
và chế độ khác nếuu khác 1
Và ở bit thứ 31,nếu mang giá trị 1 thì cr3 được sử dụng để thực hiện cơ chế phân
trang.Ở đoạn dưới khi nói về cr3,ta sẽ được cung cấp rõ hơn kiến thức này
cr1 cr2
các control register(CR) này đóng 1 số vai trò,nhưng không quan trọng.vì sao như
thế thì đây đúng là 1 vấn đề phức tạp,nó còn mang cả tính lịch sử.Các bạn google
"Why is there no CR1" của tác giả gì đó không nhớ lắm
cr3
dùng để lưu giá trị trong mỗi lần context switch :
Trong Windows, mỗi process có Page Directory và Page Table của chính nó. Vì
vậy Windows cấp 4MB của vùng space này cho mỗi process. Khi một process
được cài đặt, mỗi thành phần trong Page Directory chứa addr vật lý (physical
address) của Page Table. Các thành phần trong Page Table hoặc là valid (hợp lệ) ,
hoặc là invalid (ko hợp lệ).
Các thành phần valid chứa physical address của 4KB page cấp cho process. Một
thành phần invalid (ko hợp lệ) chứa một vài bits đặc biệt đánh dấu nó ko hợp lệ
7. và các thành phần này được biết như Invalid PTEs.
Khi memory được cấp cho process,các thành phần trong Page Table được lắp các
addr vật lý của các pages đã cấp. Bạn nên nhớ một điều ở đây là một process ko
biết bất kỳ gì về addr vật lý và nó chỉ sử dụng logical addr (địa chỉ luân lý).Chi
tiết về việc logical addr nào tương ứng với physical addr nào được quản lý chuyển
đổi bởi Windows Memory Manager và Processor (bộ vi xử lý).
Addr tại Page Directory nào của một process được định vị trong physical memory
được tham chiếu đến như là Page Directory Base address. Page Directory Base
address này được chứa trong một thanh ghi đặc biệt của CPU là CR3 (trên nền
x86). Để chuyển đổi context khác, Windows tải một giá trị mới của CR3 để trỏ
đến một Page Directory base mới của process. Với cách này mỗi process sẽ lấy
được các phần phân chia cả 4GB physical addr space của chính nó.
Tất nhiên tổng memory cấp tại một thời điểm cho tất cả các process trong hệ
thống là ko thể vượt quá số lượng RAM+ kích thước pagefile nhưng theo lược đồ
đã thảo luận ở trên thì cho phép Windows cấp cho mỗi process vùng addr logical
(hay Virtual: ảo) 4GB .
CR4:
Thanh ghi debug
Trước tiên bạn nên tham chiếu đến link sau để biết về thanh ghi này
http://pdos.csail.mit.edu/6.828/2005/rea...s12_02.htm
Tổng quan:
Ngoài các thanh ghi đã nêu trên,hệ thống của chúng ta còn có các thanh ghi
debug.Nó phục vụ cho các quá trình chạp và nạp từng bước(từng ngắt 1) để thực
hiện quá trình debug sâu trong vxl.
Các thanh ghi debug được sử dụng trong đặc quyền của ring0,ring3 không xài
được.ring bị giói hạn rất nhiều trong 1 mớ khôn gian ảo của nó.Vì thế nếu có được
đặc quyền debug thì ta đã nắm được hệ thống trong tay.
Các thanh ghi dr0-dr3 : các thanh ghi debug chính
dr6 : thanh ghi trạng thái debug.Nó chứa thông tin trạng thái của 4 thanh ghi
trên
dr7 : thanh ghi điều khiển debug
1 số thông tin
Code:
For each address in registers DR0-DR3, the corresponding fields R/W0
through R/W3 specify the type of action that should cause a
breakpoint. The processor interprets these bits as follows:
00 -- Break on instruction execution only
01 -- Break on data writes only
10 -- undefined
11 -- Break on data reads or writes but not instruction fetches
8. Fields LEN0 through LEN3 specify the length of data item to be
monitored. A length of 1, 2, or 4 bytes may be specified. The values
of the length fields are interpreted as follows:
00 -- one-byte length
01 -- two-byte length
10 -- undefined
11 -- four-byte length
Hình ảnh về các thanh ghi debug :
Sẵn với vấn đề này,ta đề cập tới việc sử dụng đặc quyền debug từ các thanh ghi
debug này.Đó là ngắt debug.
Như ta đã biết ngắt 3(INT 3h) hay sử dụng trong các trình debugger như olly để
tạo ra các ngắt mềm,tạo ra điểm bẫy,dừng tạm thời chương trình thực thi để
debug.
Nhưng còn 1 ngắt cứng khá quan trọng.Nó cũng có thể dùng để tạo ra ngắt tạm
để dừng ứng dụng tạm thời.Ta đang nói đến hardware interrupt
break point(HWBP)
vậy nó làm cách nào để dừng chương trình khi không dùng ngắt?
Như ta đã đề cập,có bốn thanh ghi debug đó là : DR0, DR1, DR2, DR3, bốn thanh
ghi này sẽ được sử dụng để lưu giữ những địa chỉ mà ta thiết lập HWBP. Điều kiện
của mỗi break points để cho dừng sự thực thi của chương trình lại được lưu trong
một thanh ghi đặc biệt khác là CPU register, đó là thanh ghi DR7. Khi bất kì một
điều kiện nào thỏa mãn (TRUE) thì processor sẽ quăng một exception là INT1
9. (khà khà vậy là nó dùng INT1 nhé) và quyền điều khiển lúc này sẽ được trả về
cho trình Debug của chúng ta. Có bốn khả năng để dừng sự thực thi của một
chương trình :
Khi một câu lệnh được thực thi.
Khi nội dung của memory có thay đổi (modified).
Khi một ví trí memory được đọc ra hoặc được cập
nhật(updated).
Khi một input-output port được tham chiếu tới.
-----------------
Phần kiến thức này cũng nhằm tham chiếu đến 1 kiến thức quan trọng của kỹ
thuật anti debug được giới thiệu trong bài viết sau :
http://www.codeproject.com/Articles/3081...uide#INT2D
Với mục đích kiểm tra các thanh ghi debug.Ta cũng xác định được process của ta
có đang bị debug hay không?
Code được đưa ra như sau :
PHP Code:
// CheckHardwareBreakpoints returns the number of hardware
// breakpoints detected and on failure it returns -1.
int CheckHardwareBreakpoints()
{
unsigned int NumBps = 0;
// This structure is key to the function and is the
// medium for detection and removal
CONTEXT ctx;
ZeroMemory(&ctx, sizeof(CONTEXT));
// The CONTEXT structure is an in/out parameter therefore we have
// to set the flags so Get/SetThreadContext knows what to set or
get.
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
// Get a handle to our thread
HANDLE hThread = GetCurrentThread();
// Get the registers
if(GetThreadContext(hThread, &ctx) == 0)
return -1;
// Now we can check for hardware breakpoints, its not
// necessary to check Dr6 and Dr7, however feel free to
if(ctx.Dr0 != 0)
++NumBps;
if(ctx.Dr1 != 0)
++NumBps;
if(ctx.Dr2 != 0)
++NumBps;
if(ctx.Dr3 != 0)
++NumBps;
10. return NumBps;
}
Các nguồn tham khảo :
http://en.wikipedia.org/wiki/X86_memory_segmentation
http://www.cs.virginia.edu/~evans/cs216/guides/x86.html
http://en.wikipedia.org/wiki/Win32_Threa...tion_Block
http://en.wikipedia.org/wiki/X86_archite..._registers