Saturday, 8 November 2014

Xây dựng trình cắm cho IDA Pro - Phần 19

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>

Xây dựng trình cắm cho IDA Pro - Phần 18

5.14 Dữ liệu
Khi làm việc với tập tin đảo mã, sẽ rất hữu ích khi ta bỏ qua trình đảo mã, và làm việc trực tiếp với các byte nhị phân. IDA cung cấp những hàm sau để làm việc đó (và một số hàm khác). Tất cả những hàm bên dưới được định nghĩa trong tập tin bytes.hpp. Những hàm đó làm việc với bytes, tuy nhiên cũng có những hàm làm việc với từ (word), từ dài (long) và từ kép (qwords) (get_word(), patch_word() và những thứ khác), mà có thể được tìm thấy trong tập tin bytes.hpp. Bên cạnh việc sử dụng những hàm đó để đọc dữ liệu từ chính tập tin nhị phân, chúng có thể được dùng để đọc những dữ liệu trong bộ nhớ trong khi tiến trình được thực thi dưới trình gỡ rối. Những điều này sẽ được nói rõ hơn trong phần liên quan đến Debugger.
5.14.1 get_byte
Định nghĩa
idaman uchar ida export get byte(ea t ea)
Chú giải
Trả về byte tại địa chỉ ea trong tập tin bị đảo mã hiện tại được mở trong IDA. Trả về BADADDR nếu địa chỉ ea không tồn tại. Những hàm được sử dụng để làm việc với những khối lớn hơn là get_word(), get_long() và get_qword(). Sử dụng get_many_bytes() để làm việc với nhiều khối bytes.
Ví dụ
#include <kernwin.hpp> // For get screen ea() definition #include <bytes.hpp>
// Display the byte value for the current cursor // position. The values returned should correspond // to those in your IDA Hex view. msg("%x\n", get byte(get screen ea()));


5.14.2 get_many_bytes
Định nghĩa
idaman bool ida export
get many bytes(ea t ea, void *buf, ssize t size)
Chú giải
Lấy một dãy các byte có kích thước size, tại địa chỉ ea và đưa vào *buf
Ví dụ
#include <kernwin.hpp> // For get screen ea() definition #include


5.14.3 get_dbg_byte
Định nghĩa
idaman bool ida export
get dbg byte(ea t ea, uint32 *x)
Chú giải
Lấy một byte tại địa chỉ trong bộ nhớ ea của tiến trình đang được dò lỗi và lưu giá trị đó tại địa chỉ *x. Trả về false nếu địa chỉ đó không thể truy cập được hoặc nếu tiến trình chưa được thực thi.
Ví dụ
#include <dbg.hpp> // For get reg val() definition #include <bytes.hpp>
uint32 stackdata; regval t regval;
if (get reg val("ESP", &regval)) {
// regval.ival holds the current stack pointer taken // from the ESP register by get reg val() get dbg byte(regval.ival, &stackdata);
} else {
msg("Stack couldn't be read");
}
msg("First byte on stack is: 0x%x\n", stackdata);


5.14.4 patch_byte
Định nghĩa
patch_byte
idaman bool ida_export patch byte(ea t ea, uint32 x)
Chú giải
Thay thế byte tại địa chỉ ea với x. Byte gốc được lưu vào CSDL của IDA, và có thể được truy xuất sử dụng get_orginal_byte() (xem trong bytes.hpp). Nếu không muốn lưu byte gốc, sử dụng put_byte(ea_t ea, ulong x) thay thế. Những hàm làm việc với khối lớn hơn là put_word, put_long(), và put_qword().
Ví dụ
#include <kernwin.hpp> // For get screen ea()
#include <bytes.hpp>
// Get the flags for the byte at the cursor position. flags t flags = get flags novalue(get screen ea());
// Replace the instruction at the cursor position with // a NOP instruction (0x90).
// Unless used carefully, your executable will probably // not work correctly after this :-) if (isCode(flags))
patch byte(get screen ea(), 0x90);


5.14.5 patch_many_bytes
Định nghĩa
idaman void ida export
patch many bytes(ea t ea, const void *buf, size t size)
Chú giải
Thay thế size byte tại địa chỉ ea với nội dung của *buf
Ví dụ
#include <kernwin.hpp> // For get screen ea() et al #include <bytes.hpp>
// Prompt the user for an address, then a string
ea t addr = get screen ea();
askaddr(&addr, "Address to put string:");
char *string = askstr(0, "", "Please enter a string");
// Write the user supplied string to the address // the user specified.
patch many bytes(addr, string, strlen(string));


5.15 I/O
Như đã được đề cập tại phần 5.1, một số lượng lớn các hàm của C làm việc với I/O được thay thế bởi các hàm tương đương của IDA SDK, và nó đề nghị bạn sử dụng những hàm đó thay vì những hàm của C. Những hàm đó được định nghĩa trong diskio.hpp.
5.15.1 fopenWT
Định nghĩa
idaman FILE *ida export fopenWT(const char *file)
Chú giải
Mở một tập tin văn bản, *file, trong chế độ ghi, trả về một con trỏ FILE hoặc NULL nếu việc mở tập tin thất bại. Để mở một tập tin ở chế độ đọc, sử dụng fopenRT(), và đối với tập tin nhị phân, thay R với W. Đối với dạng đọc/ghi, sử dụng fopenM().
Ví dụ
#include <diskio.hpp>
FILE *fp = fopenWT("c:\\temp\\txtfile.txt"); if (fp == NULL)
warning("Failed to open output file.");


5.15.2 openR
Định nghĩa
idaman FILE *ida export openR(const char *file)
Chú giải
Mở một tập tin nhị phân, *file, trong chế độ chỉ đọc, trả về một con trỏ FILE hoặc kết thúc (hiển thị một thông báo lỗi và đóng IDA) nếu nó thất bại. Để mở một tập tin dạng văn bản trong chế độ chỉ đọc, thoát khi thất bại, hãy sử dụng openRT(), để mở trong chế độ đọc/ghi sử dụng openM()
Ví dụ
#include <diskio.hpp>
FILE *fp = openR("c:\\temp\\binfile.exe");


5.15.3 ecreate
Định nghĩa
idaman FILE *ida export ecreate(const char *file)
Chú giải
Tạo một tập tin nhị phân, *file, trả về một con trỏ FILE ở chế độ chỉ ghi. Hiển thị một thông báo lỗi và kết thúc nếu nó không thể tạo tập tin. Để tạo một tập tin văn bản, sử dụng createT().
Ví dụ
#include <diskio.hpp>
FILE *fp = ecreate("c:\\temp\\newbinfile.exe");


5.15.4 eclose
Định nghĩa
idaman void ida export eclose(FILE *fp)
Chú giải
Đóng tập tin được đại diện bởi con trỏ FILE *fp. Hiển thị thông báo lỗi và kết thúc nếu nó không thể đóng tập tin.
Ví dụ
#include <diskio.hpp>
// Open the file first.
FILE *fp = openR("c:\\temp\\binfile.exe");
// Close it eclose(fp);


5.15.5 eread
Định nghĩa
idaman void ida export
eread(FILE *fp, void *buf, ssize t size)
Chú giải
Đọc size byte từ tập tin được đại diện bởi con trỏ FILE *fp, vào vùng bộ đệm *buf. Nếu việc đọc không thành công, một thông điệp lỗi được hiển thị và tiếp theo đó là đóng IDA.
Ví dụ
#include <diskio.hpp> char buf[MAXSTR];
// Open the text file
FILE *fp = openRT("c:\\temp\\txtfile.txt");
// Read MAXSTR bytes from the start of the file. eread(fp, buf, MAXSTR-1);
eclose(fp);


5.15.6 ewrite
Định nghĩa
idaman void ida export
ewrite(FILE *fp, const void *buf, ssize t size)
Chú giải
Ghi size byte của *buf vào tập tin được đại diện bởi con trỏ FILE *fp. Nếu việc ghi thất bại, một thông điệp lỗi được hiển thị tiếp theo đó là kết thúc IDA.
Ví dụ
char buf[MAXSTR]; ea t saddr, eaddr;
// Create the binary dump file FILE *fp = ecreate("c:\\bindump");
// Get the address range selected, or return false if // there was no selection if (read selection(&saddr, &eaddr)) { int size = eaddr - saddr;
// Dump the selected address range to a binary file get many bytes(saddr, buf, size); ewrite(fp, buf, size);
}
eclose(fp);



Xây dựng trình cắm cho IDA Pro - Phần 17

5.11 Tìm kiếm
Những hàm sau đâu được sử dụng để tìm kiếm trong tập tin đực đảo mã bởi IDA, và được định nghĩa trong tập tin search.hpp. Cũng có nhiều hàm tìm kiếm khác được sử dụng cho những kiểu tìm kiếm khác nhau (ví dụ, lỗi) cũng có thể được tìm thấy trong tập tin search.hpp. Những hàm tìm kiếm sẽ nhận giá trị cờ, mà nó sẽ điều kiển cách làm việc của hàm tìm kiếm, những gì được tìm, vv. Những cờ này, như được lấy từ
Hầu hết trường hợp, bạn chỉ cần sử dụng SEARCH_DOWN để tìm kiếm không phân biệt hoa thường, và tiến theo chiều đi xuống của tập tin.
5.11.1 find_text
Định nghĩa
idaman ea t ida export
find text(ea t startEA, int y, int x, const char *ustr, int sflag);
Chú giải
Tìm kiếm một chuỗi ký tự trong tập tin được đảo mã, bắt đầu tại địa chỉ startEA và tọa độ x, y (cả hai có thể gán bằng 0), cho chuỗi có giá trị là *ustr, sflag có thể được gán giá trị bằng các giá trị được đề cập ở trên.
Ví dụ
#include <kernwin.hpp> // For askstr() definition #include <search.hpp>
char *s = askstr(0, "", "String to search for", NULL);
// Find the first occurrence of the string
ea t foundAt = find text(inf.minEA, 0, 0, s, SEARCH DOWN); while (foundAt != BADADDR) {
msg("%s was found at %a\n", s, foundAt);
}


5.11.2 find_binary
Định nghĩa
idaman ea t ida export
find binary(ea t startea, ea t endea, const char *ubinstr, int radix, int sflag)
Chú giải
Tìm kiếm giữa địa chỉ startEA và endEA cho chuỗi trong tham số *ubinstr. Cơ số là một hệ số (nếu bạn tìm kiếm số), có thể là 8 (bát phân), 10 (thập phân), 16 (thập lục phân). Sflag có thể là bất cứ cờ nào bên trên.
Chú ý hàm này không tìm kiếm chuỗi kí tự đã được đảo mã mà bạn nhìn thấy trong IDA, nhưng nó tìm kiếm trong tập tin nhị phân.
Ví dụ
#include <kernwin.hpp> // for askstr() and jumpto() #include <search.hpp>


5.12 IDB
Những hàm sau đây được sử dụng để làm việc với tập tin cơ sở dữ liệu của IDA, nó có thể được tìm thấy trong loader.hpp. Mặc dù không có định nghĩa thật sự nào của lớp linput_t, bạn cần phải gọi hàm open_linput() (diskio.hpp) để tạo một thực thể của lớp này, với một vài hàm được sử dụng như là tham số. Bạn có thể sử dụng make_linput() để chuyển một con trỏ FILE thành một thực thể kiểu linput_t, xem thêm thông tin trong tập tin loader.hpp
5.12.1 open_linput
Định nghĩa
idaman linput t *ida export
open linput(const char *file, bool remote)
Chú giải
Tạo một thực thể của lớp linput_t cho tập tin có đường dẫn *file. Nếu tập tin b xóa, tham số remote sẽ được gán thành true. Trả về NULL nếu thất bại khi mở tập tin.
Ví dụ
#include <kernwin.hpp> // For askfile cv definition #include <diskio.hpp>
// Prompt the user for a file
char file = askfile cv(0, "", "File to open", NULL); // Open the file
linput t *myfile = open linput(file, false);
if (myfile == NULL)
msg("Failed to open or corrupt file.\n");
else
// Return the size of the opened file. msg("File size: %d\n", qlsize(myfile));


5.12.2 chose_linput
Định nghĩa
idaman void ida export close linput(linput t *li)
Chú giải
Đóng tập tin được đại diện bởi thực thể linput_t *li, được tạo bởi open_linput().
Ví dụ
#include <loader.hpp>


5.12.3 load_loader_module
Định nghĩa
idaman int ida export
load loader module(linput t *li, const char *lname, const char *fname, bool is remote)
Chú giải
Nạp một tập tin vào CSDL IDB hiện tại, có thể là một thực thể kiểu linput_t, *li, hoặc là tên tập tin trong *fname, sử dụng modun nạp *lname. Nếu *li có giá trị NULL, *fname phải được cung cấp và ngược lại. Trả về 1 nếu thành công, 0 nếu thất bại.
Ví dụ
#include <kernwin.hpp> // For askfile cv()


5.12.4 load_binary_file
Định nghĩa
idaman bool ida export
load binary file(const char *filename, linput t *li, ushort neflags, long fileoff, ea t basepara, ea t binoff, ulong nbytes);
Chú giải
Nạp tập tin nhị phân *li, có tên là filename tại địa chỉ bắt đầu fileoff. Nflags là bất cứ giá trị cờ nào được định nghĩa trong kiểu liệt kê NEF tại tập tin loader.hpp. nbytes xác định số byte được nạp từ tập tin, 0 sẽ nạp toàn bộ tập tin. Basepara là đoạn mà tập tin nhị phân mới này sẽ được nạp, và binoff là địa chỉ trong đoạn đó. Bạn có thể yên tâm gán basepara đến địa chỉ mà bạn muốn tập tin được nạp và gán binoff bằng 0. Trả về sai nếu việc nạp thất bại.
Ví dụ
// Ask the user for a filename
char file = askfile cv(0, "", "DLL file..", NULL);


5.12.5 gen_file
Định nghĩa
idaman int ida_export
gen_file(ofile_type_t otype, FILE *fp, ea_t eal, ea_t ea2, int flags)
Chú giải
Tạo ra tập tin kết xuất, *fp, dựa trên tập tin CSDL IDB đang mở. ea1 và ea2 là địa chỉ bắt đầu và kết thúc tương ứng, tuy nhiên giá trị này được bỏ qua đối với một vài kiểu kết xuất. otype phải được đặt như sau. Giá trị được lấy từ loader.hpp.
Ví dụ



5.12.6 save_database
Định nghĩa
idaman void ida export
save database(const char *outfile, bool delete unpacked)
Chú giải
Lưu lại tập tin CSDL theo đường dẫn được cho bởi *output. Nếu tham số delete_unpacked có giá trị false, tập tin được giải nén tạm thời không được xóa. Hàm này không trả về bất cứ giá trị nào, bởi vậy không thể xác định được là việc lưu trữ có thành công hay không, ngoại trừ việc kiểm tra tập tin có tồn tại sau khi hàm được gọi hay không.
Ví dụ
#include <loader.hpp>
msg("Saving database..."); char *outfile = "c:\\myidb.idb"; save database(outfile, false);
// There was an error if the filesize is <= 0 if (qfilesize(outfile) <= 0) msg("failed.\n");
else
msg("ok\n");


5.13 Cờ
Những hàm bên dưới được dùng để kiểm tra những cờ cụ thể (xem phần 4.3) có được đặt cho một byte trong tập tin được disassemble hiện tại hay không. Tất cả chúng được định nghĩa trong bytes.hpp.
5.13.1 get_flags_novalue
Định nghĩa
inline flags t idaapi get flags novalue(ea t ea)
Chú giải
Trả về cờ được đặt cho địa chỉ ea. Bạn sẽ cần phải chạy hàm này để lấy cờ cho một địa chỉ trước khi sử dụng các hàm như isHead(), isCode(), vv.
Ví dụ
#include <kernwin.hpp> // For get screen ea() definition #include <bytes.hpp>
msg("Flags for %a are %08x\n", get screen ea(),
get flags novalue(get screen ea()));


5.13.2 isEnabled
Định nghĩa
idaman bool ida export isEnabled(ea t ea)
Chú giải
Địa chỉ ea có tồn tại trong tập tin được diassemble hay không?
Ví dụ
#include <kernwin.hpp> // For askaddr() definition #include <bytes.hpp>
ea t addr;
askaddr(&addr, "Address to look for:");
if (isEnabled(addr))
msg("%a found within the currently opened file(s).", addr);
else
msg("%a was not found.\n");


5.13.3 isHead
Định nghĩa
inline bool idaapi isHead(flags t F)
Chú giải
Tập cờ F có phải là đánh dấu bắt đầu của mã hoặc dữ liệu ?
Ví dụ
#include <kernwin.hpp>


5.13.4 isCode
Định nghĩa
inline bool idaapi isCode(flags t F)
Chú giải
Tập cờ F đánh dấu bắt đầu chỉ thị? Hàm này giống như isHead(), nhưng chỉ trả về true đối với code, với dữ liệu thì không. Bởi vậy, nếu bạn sủe dụng một mã byte không phải là byte đầu, nó sẽ trả về sai.
Ví dụ
#include <segment.hpp> // For segment functions #include <bytes.hpp>


5.13.5 isData
Định nghĩa
inline bool idaapi isData(flags t F)
Chú giải
Tập cờ F có đánh dấu đoạn đầu của dữ liệu ? Hàm này giống như isHead() nhưng chỉ trả về đúng nếu là dữ liệu, không phải là code. Bởi vậy, nếu được sử dụng trong một byte dữ liệu mà không phải là byte đầu, nó sẽ trả về sai.
Ví dụ
#include <segment.hpp> // For segment functions #include <bytes.hpp>
for (int i = 0; i < get segm qty(); i++) { segment t *seg = getnseg(i); if (seg->type == SEG DATA) {
// Look for any bytes in the data segment that // aren't data (possibly code).
for (ea t a = seg->startEA; a < seg->endEA; a++) { flags t flags = get flags novalue(a); if (isHead(flags) && !isData(flags))
msg("Non-data at %a in segment: %s.\n", a,
get segm name(seg));
}
}
}


5.13.6 isUnknown
Định nghĩa
inline bool idaapi isUnknown(flags t F)
Chú giải
Tập cờ F có đánh dấu byte đã không được phân tích bởi IDA hay không ?
Ví dụ
#include <segment.hpp> // For segment functions #include <bytes.hpp>
// Loop through every segment for (int i = 0; i < get segm qty(); i++) { segment t *seg = getnseg(i);
// Look for any unexplored bytes in this segment for (ea t a = seg->startEA; a < seg->endEA; a++) { flags t flags = get flags novalue(a); if (isUnknown(flags))
msg("Unknown bytes at %a in segment: %s.\n", a,
get segm name(seg));
}
}