4.4.3
Điểm dừng
Một
trong những chức năng cơ bản của trình gỡ rối là cho
phép tạo ra các điểm dừng (breakpoint), IDA sử dụng điểm
dừng cứng (hardware breakpoint) và điểm dừng mềm
(software breakpoint) một cách khác nhau sử dụng cấu trúc
bpt_t, được trình bày bên dưới và được định nghĩa
trong tập tin dbg.hpp. Điểm dừng cứng được tạo ra bởi
việc sử dụng những thanh ghi dò lỗi đặc biệt có sẵn
trên Vi Sử Lý (DR0 – DR3 trên dòng X86), trong khi điểm
dừng mềm dược tạo ra bởi việc chèn vào chỉ thị
INT3 ở một địa chỉ ngắt cụ thể - mặc dù điều này
được đảm nhiệm bởi IDA, cũng sẽ rất hữu ích khi
bạn biết sự khác biệt. Trên vi sử lý x86, số lượng
điểm dừng cứng bạn có thể sử dụng là 4.
struct bpt_t
{
// read only
characteristics:
ea_t ea; //starting
address of the breakpoint
asize_t size; //
size of the breakpoint
// (undefined if
software breakpoint)
bpttype_t type; //
type of the breakpoint:
// Taken from the
bpttype_t const definition in idd.hpp:
// BPT_EXEC = 0, //
Execute instruction
// BPT_WRITE = 1, //
Write access
// BPT_RDWR = 3, //
Read/write access
// BPT_SOFT = 4; //
Software breakpoint
// modifiable
characteristics (use update_bpt() to modify):
int pass_count; //
how many times does the execution reach
// this breakpoints?
(-1 if undefined)
int flags;
#define BPT_BRK 0x01
// does the debuger stop on this breakpoint?
#define BPT_TRACE
0x02 // does the debugger add trace informaton
// when this
breakpoint is reached?
char
condition[MAXSTR]; // an IDC expression which will be used as
// a breakpoint
condition or run when the
// breakpoint is hit
};
|
Bởi
vậy, nếu kiểu thành viên của bpt_t được đặt là 0,
1, hoặc 3, thì nó là điểm dừng cứng, khi mà 4 sẽ xác
định nó là điểm dừng mềm.
Có
rất nhiều hàm để tạo ra, thao tác và đọc những chỉ
thị, nhưng hiện tại, Tôi sẽ chỉ cung cấp một ví dụ
đơn giản mà sẽ duyệt qua tất cả các định nghĩa điểm
dừng, và hiển thị chúng là điểm dừng mềm hoặc điểm
dừng cứng trên cửa sổ Log của IDA. Những hàm được
dùng sẽ được trình bày chi tiết sau:
#include
<dbg.hpp>
//
get_bpt_qty() gets the number of breakpoints defined
for
(int i = 0; i < get_bpt_qty(); i++) {
bpt_t
brkpnt;
//
getn_bpt fills bpt_t struct with breakpoint information based
//
on the breakpoint number supplied.
getn_bpt(i,
&brkpnt);
//
BPT SOFT is a software breakpoint
if
(brkpnt.type == BPT_SOFT)
msg("Software
breakpoint found at %a\n", brkpnt.ea);
else
msg("Hardware
breakpoint found at %a\n", brkpnt.ea);
}
|
4.4.4
Dò lỗi
Trong
IDA, có ba kiểu dò lỗi mà bạn có thể kích hoạt; Dò
lỗi theo hàm; dò lỗi theo chỉ thị và dò lỗi theo điểm
dừng (được biết đến như là read/write/execute). Khi viết
plugin, một cửa sổ phụ để dò lỗi được hiển thị.;
Dò theo bước. Dò theo bước là một hình thức thấp của
dò lỗi cho phép bạn xây dựng cơ chế dò lỗi dựa trên
nó, sử dụng cảnh báo sự kiện (xem phần 4.5) để thông
bao cho plugin mỗi chỉ thị được thực thi. Điều này
dựa trên chức năng dò của CPU, không phải điểm dừng.
Một
“sự kiện dò” được tạo ra và lưu trữ trong bộ đệm
khi một việc dò xảy ra, và những sự kiện dò được
tạo ra và kích hoạt dựa vào kiểu dò bạn đã kích
hoạt, tuy nhiên, chú ý rằng dò theo bước sẽ không tạo
ra sự kiện dò, nhưng thay vào đó là tạo ra sự kiện
cảnh báo. Bảng bên dưới liệt kê tất cả những kiểu
sự kiện dò cùng với giá trị tev_type_t tương ứng, được
định nghĩa trong tập tin dbg.hpp.
Kiểu dò |
Kiểu sự kiện (tev_type_t) |
Mô tả |
Function call and return |
tev_call và tev_ret |
A function has been called or returned from. |
Instruction |
tev_insn |
An instruction has been executed (this is built on top of step
tracing in the IDA kernel). |
Breakpoint |
tev_bpt |
A breakpoint with tracing enabled has been hit. Also known as a
Read/Write/Execute trace. |
Tất
cả các sự kiện dò được lưu trữ trong một bộ đệm
vòng, bởi vậy nó không bao giờ bị đầy, những những
sự kiện dò cũ sẽ bị ghi đề nếu bộ đệm quá nhỏ.
Mỗi sự kiện dò được thể hiện bởi cấu trúc
tev_info_t, được định nghĩa trong tập tin dbg.hpp.
struct tev_info_t
{
tev_type_t type; //
trace event type (one of the above or tev_none)
thid_t tid; //
thread where the event was recorded
ea_t ea; // address
where the event occurred
};
|
Dựa
vào cấu strúc bpt_t được trình bày trong phần 4.4.3, một
điểm dừng dò lỗi sẽ giống như một điểm dừng thông
thường, nhưng có cờ BPT_TRACE được đặt trong biến
thành viên flags. Bộ đệm theo điều kiện có thể chứa
các lệnh IDC để chạy tại mỗi điểm dừng.
Thông
tin dò được lấy trong suốt quá trình thực thi tiến
trình, nhưng chỉ có thể được truy cập khi tiến trình
đã kết thúc và bạn trở về chế độ đảo mã tĩnh
(trừ khi một trình cắm mà bạn sử dụng xóa bộ đệm
khi kết thúc một cách tường min). Bạn có thể dùng đoạn
mã sau để liệt kê tất cả các sự kiện dò, dù bạn
có kích hoạt nó trong khi thực thi hay không.
#include <dbg.hpp>
// Loop through all
trace events
For (int I = 0; I <
get_tev_qty(); i++) {
Regval_t esp;
Tev_info_t tev;
// Get the trace
event information
Get_tev_info(I,
&tev);
Switch (tev.type) {
Case tev_ret:
Msg(“Function
return at %a\n”, tev.ea);
Break;
Case tev_call:
Msg(“Function
called at %a\n”, tev,ea);
Break;
Case tev_insn:
Msg(“Instruction
executed at %a\n”, tev.ea);
Break;
Case tev_bpt:
Msg(“Breakpoint
with tracing hit at %a\n”, tev.ea);
Break;
Default:
Msg(“Unknown trace
type..\n”);
}
}
|
Chú
ý rằng tại thời điểm này thì một plugin không thể
nào thêm, hoặc thậm chí thay đổi giá trị trong nhật ký
dò sự kiện.
Tất
cả các hàm được sử dụng ở trên sẽ được trình
bày trong Chương 5 – Hàm.
4.4.5
Tiến trình và Tiểu trình
IDA
quản lý những thông tin về tiến trình và tiểu trình
hiện tại đang chạy trong trình gỡ rối. Số định danh
của tiến trình và tiểu trình được đại diện bằng
kiểu pid_t và thid_t, cả hai đều là kiểu nguyên có dấu.
Tất cả các kiểu được định nghĩa trong tập tin
idd.hpp. Kiểu duy nhất còn lại liên hệ với tiến trình
là process_into_t, như được trình bày bên dưới:
struct
process_info_t {
pid_t pid; //
Process ID
char name[MAXSTR];
// Process Name (executable file name)
};
|
Chúng
chỉ có thể được sử dụng khi tập tin nhị phân được
thực thi với IDA (bạn không thể sử dụng chúng trong chế
độ tĩnh). Ví dụ tiếp theo sẽ trình bày việc sử dụng
của cấu trúc info_t.
#include <dbg.hpp>
// Get the number
of processes available for debugging.
//
get_process_qty() also initilises IDA's "process snapshot"
if
(get_process_qty() > 0) {
process_info_t pif;
get_process_info(0,
&pif);
msg("ID: %d,
Name: %s\n", pif.pid, pif.name);
} else {
msg("No
process running!\n");
}
|
Những
hàm được sử dụng với cấu trúc này sẽ được trình
bày trong Chương 5 – Hàm.
4.5
Cảnh báo sự kiện
Hầu
hết, những plugin được chạy đồng bộ, trong trường
hợp đó, chúng được thực thi bởi người dùng, thông
qua việc nhấn phím tắt hoặc qua thực đơn Edit->Plugins.
Một plugin có thể, tuy nhiên, chạy trong chê độ bất
đồng bộ, khi nó được gọi bởi IDA để phản hồi một
vài sự kiện được gây ra bởi người dùng hoặc chính
bản thân IDA.
Trong
suốt khóa học làm việc với IDA, hầu hết bạn sẽ nhấn
những nút lệnh, tìm kiếm, và những thứ khác. Tất cả
những hành động đó là các “sự kiện”, và những gì
IDA phải làm là tạo ra các “cảnh báo sự kiện” mỗi
khi những hành động đó xảy ra. Nếu plugin của bạn
được cài đặt để nhận những cảnh báo đó (được
trình bày bên dưới), nó có thể hành động bất cứ gì
như bạn muốn nó làm. Một ứng dụng cho loại hình này
là bạn có thể ghi lại những macro. Một plugin có thể
tạo ra những sự kiện, khiến IDA thực hiện một loạt
các chức năng, có thể những sự kiện gây ra một loạt
các tương tác giữa các plugin.
4.5.1
Nhận cảnh báo
Để
nhận một cảnh báo sự kiện từ IDA, tất cả các plugin
phải được đăng ký vào một hàm call-back sử dụng hàm
hook_to_notification_point(). Để tạo ra sự kiện cảnh báo,
hàm callui() được sử dụng, nó sẽ đực trình bày chi
tiết trong Chương 5 – Hàm.
Khi
đăng ký một hàm call-back với hook_to_notification_point(),
bạn có thể xác định sử dụng một trong ba kiểu sự
kiện, tùy thuộc vào loại cảnh báo nào bạn muốn nhận.
Chúng được định nghĩa trong kiểu liệt kê type_t khai
báo trong loader.hpp.
Kiểu
|
Nhận sự kiện cảnh báo từ
|
Liệt kê tất cả các sự kiện cảnh
báo
|
HT_IDP
|
Processor module
|
idp_notify (không được đề cập ở
đây)
|
HT_IDB
|
Database
|
idp_event_t (không được đề cập ở
đây)
|
HT_UI
|
IDA user interface
|
ui_notification_t
|
HT_DBG
|
Currently running IDA debugger
|
dbg_notification_t
|
Bởi
vậy, để nhận tất cả các cảnh báo được phát sinh
bởi trình gỡ rối và chuyển chúng vào hàm dbg_callback(ví
dụ), bạn có thể đặt nó vào trong hàm IDAP_init():
Tham
số thứ ba thường có giá trị NULL, trừ khi bạn muốn
truyền dữ liệu cùng với hàm call-back khi snó nhận một
sự kiện (bất cứ cấu trúc nào mà bạn chọn).
Hàm
call-back được truyền vào hook_to_notification_point() sẽ có
hình thức giống như này:
int
idaapi dbg_callback (void *user_data, int notif_code, va_list va)
{
…….
return
0;
}
|
Trong
khi dbg_callback() thậm chí được gọi bởi IDA để
đảm nhiệm những cảnh báo sự kiện, user_data có thể
trỏ đến bất cứ dữ liệu nào bạn xác định để
truyền qua hàm call-back (được định nghĩa khi gọi hàm
hook_to_notification_point()), notif_code sẽ là sự kiện
thực được xác định (được liệt kê trong phần sau)
và là bất cứ dữ liệu nào được cung cấp bởi IDA
cùng với sự kiện, có thể cung cấp những thông tin
thêm.
Hàm
call-back sẽ trả về 0 nếu nó cho phép cảnh báo sự kiện
được thực hiện tởi những hàm con tuần tự (trong hầu
hết trường hợp), hoặc bất cứ giá trị nào khác nếu
nó là hàm duy nhất/cuối cùng đảm nhiệm.
Một
vài điều cần chú ý là nếu bạn sử dụng hàm
hook_to_notification_point() trong plugin của mình, bạn
cũng sẽ phải sử dụng unhook_from_notification_point(),
khi mà bạn không cần nhận cảnh báo nữa, hoặc trong hàm
IDAP_term(). Điều này sẽ tránh xảy ra trường hợp lỗi
khi kết thúc IDA. Tiếp tục theo ví dụ ở trên, để tháo
kết nối điểm kết nối, chúng ta sẽ làm như sau:
unhook_from_notification_point(ht_dbg,
dbg_callback, null);
4.5.2
Cảnh báo sự kiện UI
ui_notification_t
là một kiểu liệt kê được định nghĩa trong
kernwin.hpp, và bao gồm tất cả các sự kiện cảnh báo về
giao diện có thể được tạo ra bởi IDA hoặc một
plugin. Để đăng ký những cảnh báo sự kiện này, bạn
phải sử dụng hằng số HT_UI như là tham số đầu tiên
của hook_to_notification_point().
Hai
danh sách sau sẽ cho thấy một vài cảnh báo sự kiện có
thể được nhận và tạo ra bởi plugin. Đó chỉ là những
tập con của một tập các cảnh báo sự kiện; danh sách
bên dưới có một ý nghĩa tổng quát hơn.
Mặc
dù những thông tin bên dưới có thể được tạo ra bởi
plugin sử dụng hàm callui(), hầu hết có những hàm trợ
giúp, điều đó có nghĩa là bạn sẽ không phải sử dụng
callui() và có thể chỉ cần gọi những hàm trợ giúp.
Sự
kiện cảnh báo bên dưới được nhận bởi plugin, và sẽ
được thực hiện bởi hàm call-bak của bạn.
Event
|
Description
|
Helper Function
|
Ui_jumpto
|
Moves the cursor to an address
|
Jumpto
|
Ui_screenea
|
Return the address where the cursor is
currently positioned
|
Get_screen_ea
|
ui_refresh
|
Refresh all disassembly views
|
Refresh_idaview_anyway
|
ui_mbox
|
Display a message box to the user
|
vwarning, vinfo and more.
|
Ui_msg
|
Print some text in IDA's Log window
|
deb, vmsg
|
Ui_askyn
|
Dislpay a message box with Yes and No as
options
|
Askbuttons_cv
|
Ui_askfile
|
Prompt the user for a filename
|
askfile_cv
|
Ui_askstr
|
Prompt the user for a single line string
|
vaskstr
|
Ui_asktext
|
Prompt the user for some text
|
vasktext
|
ui_form
|
Display a form (very flexible - look at the
comments in the header!)
|
AskUsingForm_cv
|
ui_open_url
|
Open a web browser at a particular URL
|
Open_url
|
Ui_get_hwnd
|
Get the hwnd (Window Handle) for the IDA window
|
none
|
Ui_get_curline
|
Get the colour-coded disassembled line
|
Get_curline
|
Ui_get_cursor
|
Get the X and Y coordinates of the current
cursor position
|
Get_cursor
|
Những
cảnh báo sự kiện tiếp theo được nhận bởi plugin, và
nên được đảm nhiệm bởi hàm callback của bạn.
Event Notification
|
Description
|
ui saving & ui saved
|
IDA is currently saving and has saved the
database, respectively
|
ui term
|
IDA has closed the database
|
Ví
dụ, đoạn mã phía dưới sẽ tạo ra một cảnh báo sự
kiện ui_screenea và hiển thị kết quả trong hộp thoại
của IDA sử dụng một sự kiện cảnh báo ui_mbox.
void
IDAP_run(int arg)
{
ea_t addr;
va_list va;
char
buf[MAXSTR];
// Get the
current cursor position, store it in addr
callui(ui_screenea, &addr);
qsnprintf(buf,
sizeof(buf)-1, "Currently at: %a\n", addr);
// Display an
info message box
callui(ui_mbox,
mbox_info, buf, va);
return;
}
|
Trong
trường hợp trên, bạn sử dụng hầu hết các hàm trợ
giúp, tuy nhiên callui() sẽ được dùng với mục đích
miêu tả. Phần tiếp theo mô tả làm thế nào để phản
hồi những sự kiện với plugin của bạn.
No comments:
Post a Comment