5.16
Dò lỗi
Ba
phần sau sẽ làm việc với giá trị nhị phân trong suốt
quá trình thực thi. Phần này sẽ tập trung vào những
thao tác bậc cao (như là điều khiển tiến trình và tiểu
trình) trong một tập tin nhị phân/tiến trình. Dò lỗi và
duyệt được trình bày trong hai phần tiếp theo. Tất cả
những hàm bên dưới được định nghĩa trong tập tin
dbg.hpp với 2 ngoại lệ là invalidate_dbg_contents() và
invalidate_dbg_config(), được định nghĩa trong bytes.hpp. Để
hiểu rõ hơn về chúng, bạn cần phải chạy chúng (gọi
plugin của bạn) trong một tập tin đang được dò lỗi
bởi IDA.
Bạn
sẽ nhận thấy rằng tất cả những hàm này không được
đặt tiền tố bởi ida_export. Chúng không cần thiết bởi
vì tất cả chúng là những hàm bao của callui(), và sử
dụng những cảnh báo sự kiện tương ứng với chức
năng của mình.
5.16.0
Chú ý về loại hàm Request
Không
giống như hầu hết các hàm trong SDK, hầu hết các hàm
của trình gỡ rối (và một vài hàm duyệt) được chia
làm hai hình thức; hình thức bất đối xứng thông
thường, ví dụ run_to(), và hình thức đồng bộ, hoặc
hình thức request, như request_run_to(). Cả hai hình thức
của hàm đều nhận cùng một dạng tham số, nhưng nó
khác nhau ở những tác vụ tương ứng tạo cho nó sự
khác biệt.
Hình
thức hàm đồng bộ (request_) sẽ được nhập vào một
hàng đợi hàm, và cuối cùng được thực thi bởi IDA khi
bạn gọi hàm run_requests(). Hình thức còn lại, những hàm
không đồng bộ, sẽ chạy một mạch, giống như những
hàm thôn thường.
Hình
thức hàm đồng bộ có thể rất hữu dụng khi bạn muốn
thực thi một loạt các thao tác trong IDA khi được kích
hoạt. Ví dụ 5.17.5 là một ví dụ tốt cho điều này,
khi xóa một loạt các điểm dừng sử dụng hàm del_bpt()
sẽ thất bại trừ khi nó được làm trong chế độ đồng
bộ, bởi vì số định danh của điểm dừng sẽ được
tổ chức lại bởi lần mà bạn lấy giá trị kế tiếp
bằng việc sử dụng hàm getn_bpt(). Một điều quan trọng
cần chú ý là bạn phải sử dụng hình thức đồng bộ
của hàm khi bạn ở trong một cảnh báo sự kiện của
trình gỡ rối (xem phần 4.5, đặc biệt là 4.5.3 đễ biết
rõ thêm).
Tất
cả các hàm trong phần 5.16, 5.17 và 5.18 mà có thể được
dùng dưới hai dạng sẽ được thêm dấu sao (*) ngay sau
tên hàm.
5.16.1
run_requests
Định nghĩa
|
bool idaapi
run requests(void)
|
Chú giải
|
Chạy bất cứ yêu cầu nào (các hàm
đồng bộ) đã được đặt trong hàng đợi.
|
Ví dụ
|
#include <dbg.hpp>
// Run to the entry
point of the binary request run to(inf.startlP);
// Enable function
tracing request enable func trace();
// Run the above requests run requests();
|
5.16.2
get_proces_state
Định nghĩa
|
int idaapi
get process state(void)
|
Chú giải
|
Trả về trạng thái của tiến trình
dang được dò lỗi. Nếu tiến trình đã bị đóng
băng, -1 sẽ được trả về, trả về 1 nếu tiến
trình đang chạy hoặc 0 nếu không có tiến trình nào
đang chạy trong trình gỡ rối.
|
Ví dụ
|
#include <dbg.hpp>
switch (get process
state()) { case DSTATE SUSP FOR EVENT:
msg("Suspended
to react to debug event.\n"); break; case DSTATE NOTASK:
msg("No process
running.\n"); break; case DSTATE SUSP:
msg("Process is
suspended.\n"); break; case DSTATE RUN:
msg("Process is
running.\n"); break;
case DSTATE RUN WAIT
ATTACH
msg("Process is
running, waiting for attach.\n"); break;
case DSTATE RUN WAIT
END
msg("Running,
user requested kill/detach.\n"); break; default:
msg("Unknown status.\n");
|
5.16.3
get_process_qty
Định nghĩa
|
int idaapi
get process qty(void)
|
Chú giải
|
Trả về số lượng tiến trình tướng
ứng với ảnh của tập tin đang được thực thi trong
IDA. Hàm này cũng cần được gọi để khởi tạo ảnh
tiến trình, mà sẽ được sử dụng bởi IDA để thao
tác với những cấu trúc dữ liệu được dùng bởi
những hàm khác liên quan đến tiến trình.
|
Ví dụ
|
#include <dbg.hpp>
msg("There are %d processes running.\n",
get process qty());
|
5.16.4
get_process_info
Định nghĩa
|
pid t idaapi
get process info(int n, process info t *process
info);
|
Chú giải
|
Gán vào *process_info với thông tin về
tiến trình có số thứ tự n (đây không phải là định
danh tiến trình PID). Định dạng của tiến trình thứ
n sẽ được trả về. nếu *process_info là null, thì chỉ
có PID của tiến trình được trả về.
|
Ví dụ
|
#include <dbg.hpp>
// Only get the info
if a process is actually running. if (get process qty() > 0) {
process info t pif;
// Populate pif
get process info(0,
&pif);
msg("ID: %d,
Name: %s\n", pif.pid, pif.name);
} else {
msg("No process
running!\n");
}
|
5.16.5
start_proces *
Định nghĩa
|
int idaapi
start process(const char *path = NULL, const
char *args = NULL, const char *sdir = NULL);
|
Chú giải
|
Bắt đầu quá trình dò lỗi của tiến
trình *path với tham số truyền vào *args, trong thư mục
*sdir. Nếu bất cứ tham số nào là null, chúng sẽ được
lấy trong tùy chọn tiến trình được xác định trong
Debugger->Process Options … Điều này giống như là khi
bạn nhấn F9 trong IDA.
|
Ví dụ
|
#include
<kernwin.hpp> // For askstr()
#include <dbg.hpp>
// Ask the user for
arguments to supply.
char *args =
askstr(HIST IDENT, "", "Arguments");
// Run the process with those arguments start
process(NULL, args, NULL);
|
5.16.6
continue_process *
Định nghĩa
|
bool idaapi continue process(void)
|
Chú giải
|
Tiếp tục thực thi tiến trìh. Trả về
false nếu việc tiếp tục tiến trình thất bại. Điều
này tương tự như khi bạn nhấn F9 trong IDA khi một
tiến trình ở trong trạng thái tạm dừng (điểm dừng
được kích hoạt hoặc tạm dừng).
|
Ví dụ
|
#include <dbg.hpp>
// Continue running
the process when the user // involkes this plug-in. if (continue
process())
msg("Continuing
process..\n");
else
msg("Failed to continue process
execution.\n");
|
5.16.7
suspend_process *
Định nghĩa
|
bool idaapi suspend process(void)
|
Chú giải
|
Tạm dừng tiến trình đang được dò
lỗi. Trả về false nếu quá trình tạm dừng tiến
trình lỗi. Điều này giống như là khi bạn nhấn phím
Pause Process trong IDA.
|
Ví dụ
|
#include <dbg.hpp>
// Suspend the
process being debugged. if (suspend process())
msg("Suspended
process.\n");
else
msg("Failed to suspend process.\n");
|
5.16.8
attach_process *
Định nghĩa
|
int idaapi
attach process(pid t pid=NO PROCESS, int event
id=-1)
|
Chú giải
|
Attach vào tiến
trình có PID là pid. Tiến trình đang được attach phải
có ảnh thực thi giống như là đang được đảo mã
trong IDA. Nếu tham số pid là NO_PROCCESS, người dùng sẽ
được hỏi một danh sách các tiến trình có thể được
attach. Mã trả về có thể là những giá trị sau, mà
được lấy từ tập tin dbg.hpp
-2 không thể tìm
thấy tiến trình tương ứng
-1 không thể
attach vào tiến trình được chỉ định (tiến trình bị
chết, quyền hạn cần không được cung cấp bởi trình
gỡ rối …)
0 người dùng hủy
thao tác attach vào tiến trình
1 trình gỡ rối attach vào tiến trình
bình thường.
|
Ví dụ
|
#include <dbg.hpp>
// Present the user
with a list of processes to // attach to. If there is no
executable running that // matches what's open in IDA, no dialog
box will // be presented. int err;
if ((err = attach
process(NO PROCESS)) == 1)
msg("Successfully
attached to process.\n");
else
msg("Unable to attach, error: %d\n",
err);
|
5.16.9
detach_process *
Định nghĩa
|
bool idaapi detach process(void)
|
Chú giải
|
Detach tiến trình đang được dò lỗi.
Đây có thể là tiến trình được attach hoặc chạy
thông qua IDA. Trả về alse nếu nó không thể detach.
Detach từ một tiến trình chỉ được hỗ trợ trong
các phiên bản Windowss XP SP2 trở lên.
|
Ví dụ
|
#include <dbg.hpp>
// Detach from the
debugged process. if (detach process())
msg("Successfully
detached from process.\n");
else
msg("Failed to detach.\n");
|
5.16.10
exit_process *
Định nghĩa
|
bool idaapi exit process(void)
|
Chú giải
|
Kết thúc một tiến trình đang được
dò lỗi. Trả về false nếu nó không thể kết thúc
tiến trình.
|
Ví dụ
|
#include <dbg.hpp>
// Terminate the
debugged process. if (exit process())
msg("Successfully
terminated the process.\n");
else
msg("Failed to terminate the proces.\n");
|
5.16.11
get_thread_qty
Định nghĩa
|
int idaapi
get thread qty(void)
|
Chú giải
|
Trả về số lượng tiểu trình tồn
tại trong tiến trình đang được dò lỗi.
|
Ví dụ
|
#include <dbg.hpp>
// Only display if there is a process being
debugged. if (get process qty() > 0)
|
5.16.12
get_current_thread
Định nghĩa
|
thid t idaapi
get current thread(void)
|
Chú giải
|
Returns the ID of
the currently active thread in the debugged process.
Trả về số định danh ID của tiểu
trình hiện tại đang được kích hoạt bởi tiến trình
được dò lỗi.
|
Ví dụ
|
#include <dbg.hpp>
// Only display if
there is a process being debugged. if (get process qty() > 0)
msg("Thread ID running: %d\n", get
current thread());
|
5.16.13
getn_thread
Định nghĩa
|
thid t idaapi getn thread(int n)
|
Chú giải
|
Trả về số định danh của tiểu trình
ở vị trí thứ n. N nằm trong khoảng từ 0 đến số
lượng tiểu trình được trả về bởi hàm
get_thead_qty() - 1
|
Ví dụ
|
#include <dbg.hpp>
// Only display if
there is a process being debugged. for (int i = 0; i < get
thread qty(); i++) {
msg("Thread %d
ID: %d \n", i, getn thread(i));
}
|
5.16.14
get_reg_val
Định nghĩa
|
bool idaapi
get reg val(const char *regname, regval t
*regval)
|
Chú giải
|
Lấy giá trị chứa trong thanh ghi
*regname và lưu nó trong *regval. Trả về false nếu nó
không thể lấy giá trị từ thanh ghi. Tên thanh ghi phân
biệt hoa thường.
|
Ví dụ
|
#include <dbg.hpp>
|
5.16.15
thread_get_sreg_base(member of dbg)
Định nghĩa
|
int idaapi
thread get sreg base(thid t tid, int sreg
value, ea t *answer)
|
Chú giải
|
Với tiểu trình tid, đặt vào *answer
địa chỉ cơ sở tuyến tính được trỏ bởi thanh ghi
đoạn sreg. Trong một vài trường hợp, bạn sẽ cần
phải sử dụng địa chỉ đoạn khi đọc thông tin về
bộ nớ đang được dò lỗi (FS:0 trong Windows), mà hàm
này được sử dụng
|
Ví dụ
|
#include <idd.hpp>
#include <dbg.hpp>
// x86 segment
registers
char *srs[] = {
"CS", "DS", "ES", "FS",
"GS", "SS", 0 };
for (int i = 0;
srs[i] != 0; i++) { ea t addr; regval t sreg val;
// Because it's done
on a thread-by-thread basis, we // need to get the thread ID. thid
t tid = get current thread();
// Fetch the segment
register's value get reg val(srs[i], &sreg val);
// Get the base
address
dbg->thread get
sreg base(tid, sreg val.ival, &addr); msg("%s base is
%a\n", srs[i], addr);
}
|
5.16.16
read_memory(member of dbg)
Định nghĩa
|
ssize t idaapi
read memory(ea t ea, void *buffer, size t size)
|
Chú giải
|
Đọc size byte từ bộ nhớ tại địa
chỉ ea và đưa vào *buffer. Trả về -1 nếu lỗi.
|
Ví dụ
|
#include <dbg.hpp>
#include <idd.hpp>
ea t saddr; char
chunk[1024]; int i = 0;
// Ask the user what
address to dump a string from askaddr(&saddr, "Address to
dump a string from");
// Read 1KB of data
from that address dbg->read memory(saddr, (void *)&chunk,
1024); while (i < 1024 && chunk[i] != '\0') { msg("%c",
chunk[i++]);
}
msg("\n");
|
5.16.17
write_memory(member of dbg)
Định nghĩa
|
ssize t idaapi
write memory(ea t ea, const void *buffer, size
t size);
|
Chú giải
|
Ghi size byte từ buffer vào vùng nhớ tại
địa chỉ ea. Trả về -1 nếu lỗi.
|
Ví dụ
|
#include <dbg.hpp>
#include <idd.hpp>
ea t saddr; char
chunk[1024];
// Fill up the
buffer with As memset(chunk, 'A', 1024); askaddr(&saddr,
"Address to fill");
// Overwrite 1KB of
memory with our 'A' buffer
int res = dbg->write
memory(saddr, (void *)&chunk, 1024);
if (res <= 0) {
msg("There was
an error writing to memory.");
}
|
5.16.18
set_reg_val*
Định nghĩa
|
bool idaapi
set reg val(const char *regname, const regval t
*regval)
|
Chú giải
|
Đặt giá trị của thanh ghi *regname với
giá trị được cho bởi *regval trong tiểu trình hiện
tại. Nếu việc đọc thất bại, giá trị false được
trả về. Giống như get_reg_val(), *regname có phân biệt
hoa thường. Không giống như những hàm không đồng bộ,
hàm này an toàn để được gọi từ cảnh báo sự kiện
dò lỗi.
|
Ví dụ
|
#include
<kernwin.hpp> // For get screen ea() definition #include
<dbg.hpp>
// Suspend the
currently executing process. suspend process();
// Continue
execution from the user's cursor position. ea t addr = get screen
ea(); char *regname = "EIP";
if (set reg
val(regname, addr)) {
msg("Continuing
execution from %a\n", addr); continue process();
}
|
5.16.19
invalidate_dbgmem_contents
Định nghĩa
|
idaman void ida
export
invalidate dbgmem contents(ea t ea, asize t
size)
|
Chú giải
|
Làm mất hiệu
lực size byte của bộ nhớ, bắt đầu từ địa chỉ
ea. Nếu bạn muốn làm mất hiệu lực toàn bộ vùng
nhớ của tiến trình, đặt giá trị ea thành BADADDR và
size thành 0.
Làm mất hiệu lực nội dung bộ nhớ
là thiết yếu để làm tươi lại bộ đệm bộ nhớ
của IDA cho tiến trình, việc làm này sẽ đảm bảo
rằng bạn đang truy cập vào nội dung bộ nhớ mới
nhất từ bộ nhớ của tiến trình. Bạn nên gọi hàm
này sau khi một tiến trình được tạm dừng, hoặc nếu
bạn xác định rằng nội dung bộ nhớ đã được thay
đổi.
|
Ví dụ
|
#include <dbg.hpp>
|
5.16.20
invalidate_dbgmem_config
Định nghĩa
|
idaman void ida export invalidate dbgmem
config(void)
|
Chú giải
|
Giống như hàm invalidate_dbgmem_contents(),
bạn sử dụng hàm này để chắc chắn rằng IDA đang
làm việc với cấu hình bộ nhớ mới nhất. Bạn cần
chạy hàm này nếu tiến trình được dò lỗi đã được
cấp phát hoặc cấp phát lại bộ nhớ kể từ khi nó
được tạm dừng lần cuối cùng. Hàm này cũng làm
tươi lại bộ đệm bộ nhớ của IDA, tuy nhiên nó chậm
hơn hàm invalidate_dbgmem_contents().
|
Ví dụ
|
#include <dbg.hpp>
#include <bytes.hpp>
regval t esp;
// Get ESP before
invalidate config
get reg val("ESP",
&esp);
uchar before = get
byte(esp.ival);
// Invalidate memory
config invalidate dbgmem config();
// After invalidate uchar after = get
byte(esp.ival); msg("%08a Before: %a, After: %a\n",
esp.ival, before, after);
|
5.16.21
run_to *
Định nghĩa
|
bool idaapi run to(ea t ea)
|
Chú giải
|
Chạy tiến trình đến khi thực thi đến
địa chỉ ea. Nếu không có tiến trình nào đang chạy,
tập tin bị đảo mã hiện tại sẽ được thực thi.
Trả về alse nếu nó không thể thực thi tiến trình.
|
Ví dụ
|
#include
<kernwin.hpp> // For get screen ea() definition #include
<dbg.hpp>
// Replicate F4
functionality if (!run to(get screen ea()))
msg("Failed to run to %a\n", get
screen ea());
|
5.16.22
step_into *
Định nghĩa
|
bool idaapi step into(void)
|
Chú giải
|
Chạy một chỉ thị trong tiểu trình
hiện tại của tiến trình được dò lỗi. Giống như
là khi bạn nhấn F7 trong IDA. Trả về false nếu nó
không thể nhảy vào chỉ thị.
|
Ví dụ
|
#include <dbg.hpp>
// Go to the entry
point (queued) request run to(inf.startlP);
// Run 20
instructions (queued) for (int i = 0; i < 20; i ++) request
step into();
// Run through the queue run requests();
|
5.168.23
step_over *
Định nghĩa
|
bool idaapi step over(void)
|
Chú giải
|
Chạy một chỉ thị trong tiểu trình
của tiến trình đang được dò lỗi, nhưng không nảy
vào hàm, xem hàm đó như là một chỉ thị. Giống như
chức năng F8 trong IDA. Trả về false nếu nó không thể
nhảy qua chỉ thị.
|
Ví dụ
|
#include <dbg.hpp>
// This can only run
when the process is suspended
// Step over 5 instructions. This needs to be
done as // a request, otherwise only one step will execute. for
(int i = 0; i < 5; i ++) request step over(); run requests();
|
5.16.24
step_until_ret *
Định nghĩa
|
bool idaapi
step until ret(void)
|
Chú giải
|
Thực thi mỗi chỉ thị trong tiểu trình
hiện tại của tiến trình đang được dò lỗi cho đến
khi hàm hiện tại được trả về. Hàm này giống chức
năng của CTRL + F7 trong IDA
|
Ví dụ
|
#include <dbg.hpp>
|
No comments:
Post a Comment