Saturday 8 November 2014

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

6.8 BeingDebugged Flipper (Chỉ chạy trên Windows)
//
// beingdebugged.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <kernwin.hpp>
#include <idd.hpp>
#include <dbg.hpp>

int IDAP_init(void) {
// Only support x86 architecture
if(strncmp(inf.procName, "metapc", 8) != 0 && inf.filetype != f_PE) {
warning("Only x86 PE binary type supported, sorry.");
return PLUGIN_SKIP;
}

return PLUGIN_KEEP;
}

void IDAP_term(void) {
return;
}

void IDAP_run(int arg) {

// PEB structure, built from NT Internals:
// http://undocumented.ntinternals.net
struct _PEB {
bool InheritedAddressSpace;
bool ReadImageFileExecOptions;
bool BeingDebugged;
unsigned char Junk;
long MoreJunk;
void *ImageBaseAddress;
// The rest has been left out seeing as we don't
// need it for this example.
} peb;

// Get the current thread ID
thid_t thread_id = get_current_thread();

// FS:[0] points to the Thread Information Block
ea_t seg;
regval_t fs;
get_reg_val("FS", &fs);
dbg->thread_get_sreg_base(thread_id, fs.ival, &seg);

// Load the PEB, the address of which is 0x30 bytes into the TIB
ea_t peb_addr;
msg("Reading TIB at %a\n", seg);

// PEB address lives at 0x30 bytes into the TIB
dbg->read_memory((ea_t)seg+0x30, (void *)&peb_addr, sizeof(void *));

// Read the contents of the PEB into buffer
dbg->read_memory(peb_addr, (void *)&peb, sizeof(_PEB));

msg("PEB Address: %a, Being debugged (before change): %d, "
"Image base address: %a\n",
peb_addr,
peb.BeingDebugged,
peb.ImageBaseAddress);

// Change the flag in the structure and write it to memory
peb.BeingDebugged ?
peb.BeingDebugged = false : peb.BeingDebugged = true;
dbg->write_memory(peb_addr, (void *)&peb, sizeof(_PEB));

// Re-read the contents of the PEB into buffer
dbg->read_memory(peb_addr, (void *)&peb, sizeof(_PEB));
msg("Being debugged (after change): %d\n", peb.BeingDebugged);
}

char IDAP_comment[] = "PEB BeingDebugged flipper";
char IDAP_help[] = "Switches the BeingDebugged flag in the PEB\n";
char IDAP_name[] = "BeingDebugged flipper";
char IDAP_hotkey[] = "Alt-I";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};




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

6.6 Selective Tracing (Phương pháp 2)
//
// snaptrace2.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <dbg.hpp>

ea_t start_ea = 0;
ea_t end_ea = 0;

// Handler for HT_DBG events
int idaapi trace_handler(void *udata, int dbg_event_id, va_list va)
{
regval_t esp, eip;

// Get ESP register value
get_reg_val("esp", &esp);
// Get EIP register value
get_reg_val("eip", &eip);

// We'll also receive debug events unrelated to tracing,
// make sure those are filtered out
if (dbg_event_id == dbg_trace) {
// Make sure EIP is between the user-specified range
if (eip.ival > start_ea && eip.ival < end_ea)
msg("ESP = %a\n", esp.ival);
}

return 0;
}

int IDAP_init(void)
{
// Receive debug event notifications
hook_to_notification_point(HT_DBG, trace_handler, NULL);
return PLUGIN_KEEP;
}

void IDAP_term(void)
{
// Unhook from the notification point on exit
unhook_from_notification_point(HT_DBG, trace_handler, NULL);
return;
}

void IDAP_run(int arg)
{
// Ask the user for a start and end address
askaddr(&start_ea, "Start Address:");
askaddr(&end_ea, "End Address:");
// Queue the following
// Run to the binary entry point
request_run_to(inf.startIP);
// Enable step tracing
request_enable_step_trace();
// Run queued requests
run_requests();
}

char IDAP_comment[] = "Snap Tracer 2";
char IDAP_help[] = "Allow tracing only between user "
"specified addresses\n";


char IDAP_name[] = "Snap Tracer 2";
char IDAP_hotkey[] = "Alt-I";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};



6.7 Sao chép & Dán nhị phân
//
// copypaste.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>

#define MAX_COPYPASTE 1024

// This will hold our copied buffer for pasting
char data[MAX_COPYPASTE];

// Bytes copied into the above buffer
ssize_t filled = 0;

// Insert the following two lines into your plugins.cfg file
// Replace pluginname with the filename of your plugin minus
// the extension.
//
// Copy_Buffer pluginname Alt-C 0
// Paste_Buffer pluginname Alt-V 1
//

int IDAP_init(void)
{
return PLUGIN_KEEP;
}

void IDAP_term(void)
{
return;
}

void copy_buffer() {
ea_t saddr, eaddr;
ssize_t size;

// Get the boundaries of the user selection
if (read_selection(&saddr, &eaddr)) {
// Work out the size, make sure it doesn't exceed the buffer
// we have allocated.
size = eaddr - saddr;
if (size > MAX_COPYPASTE) {
warning("You can only copy a max of %d bytes\n", MAX_COPYPASTE);
return;
}

// Get the bytes from the file, store it in our buffer
if (get_many_bytes(saddr, data, size)) {
filled = size;
msg("Successfully copied %d bytes from %a into memory.\n",
size,
saddr);
} else {
filled = 0;
}
} else {
warning("No bytes selected!\n");
return;
}
}

void paste_buffer() {

// Get the cursor position. This is where we will paste to
ea_t curpos = get_screen_ea();

// Make sure the buffer has been filled with a Copy operation first.
if (filled) {
// Patch the binary (paste)
patch_many_bytes(curpos, data, filled);
msg("Patched %d bytes at %a.\n", filled, curpos);
} else {
warning("No data to paste!\n");
return;
}
}

void IDAP_run(int arg) {

// Based on the argument supplied in plugins.cfg,
// we can use the one plug-in for both the copy
// and paste operations.
switch(arg) {
case 0:
copy_buffer();
break;
case 1:
paste_buffer();
break;
default:
warning("Invalid usage!\n");
return;
}
}

// These are actually pointless because we'll be overriding them
// in plugins.cfg
char IDAP_comment[] = "Binary Copy and Paster";
char IDAP_help[] = "Allows the user to copy and paste binary\n";

char IDAP_name[] = "Binary Copy and Paster";
char IDAP_hotkey[] = "Alt-I";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};


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

6.5 Selective Tracing (Phương pháp 1)
//
// snaptrace.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <dbg.hpp>

int IDAP_init(void)
{
return PLUGIN_KEEP;
}

void IDAP_term(void)
{
return;
}

void IDAP_run(int arg)
{
// Set the default start address to the user cursur position
ea_t eaddr, saddr = get_screen_ea();

// Allow the user to specify a start address
askaddr(&saddr, "Address to start tracing at");

// Set the end address to the end of the current function
func_t *func = get_func(saddr);
eaddr = func->endEA;

// Allow the user to specify an end address
askaddr(&eaddr, "Address to end tracing at");
// Queue the following

// Run to the start address
request_run_to(saddr);
// Then enable tracing
request_enable_insn_trace();
// Run to the end address, tracing all stops in between
request_run_to(eaddr);
// Turn off tracing once we've hit the end address
request_disable_insn_trace();
// Stop the process once we have what we want
request_exit_process();

// Run the above queued requests
run_requests();

}

char IDAP_comment[] = "Snap Tracer";
char IDAP_help[] = "Allow tracing only between user "
"specified addresses\n";


char IDAP_name[] = "Snap Tracer";
char IDAP_hotkey[] = "Alt-T";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};




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

.4 Đặt và lưu điểm dừng hàng loạt
//
// bulkbpt.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <diskio.hpp>
#include <dbg.hpp>

// Maximum number of breakpoints that can be set
#define MAX_BPT 100

// Insert the following two lines into your plugins.cfg file
// Replace pluginname with the filename of your plugin minus
// the extension
//
// Write_Breakpoints pluginname Alt-D 0
// Read_Breakpoints pluginname Alt-E 1
//

void read_breakpoints() {
char c, ea[9];
int x = 0, b = 0;
ea_t ea_list[MAX_BPT];
// Ask the user for the file containing the breakpoints
char *file = askfile_cv(0, "", "Breakpoint list file...", NULL);
// Open the file in read-only mode
FILE *fp = fopenRT(file);
if (fp == NULL) {
warning("Unable to open breakpoint list file, %s\n", file);
return;
}
// Grab 8-byte chunks from the file
while ((c = qfgetc(fp)) != EOF && b < MAX_BPT) {
if (isalnum(c)) {
ea[x++] = c;
if (x == 8) {
// NULL terminate the string
ea[x] = 0;
x = 0;
// Convert the 8 character string to an address
str2ea(ea, &ea_list[b], 0);
msg("Adding breakpoint at %a\n", ea_list[b]);
// Add the breakpoint as a software breakpoint
add_bpt(ea_list[b], 0, BPT_SOFT);
b++;
}
}
}
// Close the file handle
qfclose(fp);
}

void write_breakpoints() {
char c, ea[9];
int x = 0, b = 0;
ea_t ea_list[MAX_BPT];
// Ask the user for the file to save the breakpoints to
char *file = askstr(0, "", "Breakpoint list file...", NULL);
// Open the file in write-only mode
FILE *fp = ecreateT(file);
for (int i = 0; i < get_bpt_qty(); i++) {
bpt_t bpt;
char buf[MAXSTR];

getn_bpt(i, &bpt);
qsnprintf(buf, sizeof(buf)-1, "%08a\n", bpt.ea);
ewrite(fp, buf, strlen(buf));
}
// Close the file handle
eclose(fp);
}

void IDAP_run(int arg)
{
// Depending on the argument supplied,
// read the breakpoint list from a file and
// apply it, or write the current breakpoints
// to a file.
switch (arg) {
case 0:
write_breakpoints();
break;
case 1:
default:
read_breakpoints();
break;
}
}

int IDAP_init(void)
{
return PLUGIN_KEEP;
}

void IDAP_term(void)
{
return;
}

// These are irrelevant because they will be overridden by
// plugins.cfg.
char IDAP_comment[] = "Bulk Breakpoint Setter and Recorder";
char IDAP_help[] =
"Sets breakpoints at a list of addresses in a text file"
" or saves the current breakpoints to file.\n"
"The read list must have one address per line.\n";


char IDAP_name[] = "Bulk Breakpoint Setter and Recorder";
char IDAP_hotkey[] = "Alt-B";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};




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

6.3 Tự động nạp DLL vào CSDL IDA
//
// loadlib.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <strlist.hpp>

// Maximum number of library files to load into the IDB
#define MAXLIBS 5

int IDAP_init(void)
{
if (inf.filetype != f_PE) {
warning("Only PE executable file format supported.\n");
return PLUGIN_SKIP;
}

return PLUGIN_KEEP;
}

void IDAP_term(void)
{
return;
}

void IDAP_run(int arg)
{
char loadLibs[MAXLIBS][MAXSTR];
int libno = 0, i, strcount = get_strlist_qty();

if (strcount == 0) {
msg("No strings found in this binary or IDA hasn't finished"
" processing the binary yet.");
return;
}

msg("%d strings found, checking for DLL use..", strcount);

// Loop through all strings to find any string that contains
// .dll. This will eventuall be our list of DLLs to load.
for (i = 0; i < strcount; i++) {
char string[MAXSTR];
string_info_t si;

// Get the string item
get_strlist_item(i, &si);

if (si.length < sizeof(string)) {

// Retrieve the string from the binary'
get_many_bytes(si.ea, string, si.length);

// We're only interested in C strings.
if (si.type == 0) {

// .. and if the string contains .dll
if (stristr(string, ".dll") && libno < MAXLIBS) {

// Add the string to the list of DLLs to load later on.
qstrncpy(loadLibs[libno++], string, MAXSTR-1);
}
}
}
}

if (libno == 0) {
msg("No DLL files found in strings.");
return;
}

// Now go through the list of libraries found and load them.
msg("Loading the first %d libraries found...\n", MAXLIBS);

for (i = 0; i < libno; i++) {
msg("Lib: %s\n", loadLibs[i]);

// Ask the user for the full path to the DLL (the executable will
// only have the file name).
char *file = askfile_cv(0, loadLibs[i], "File path...\n", NULL);

// Load the DLL using the pe loader module.
if (load_loader_module(NULL, "pe", file, 0)) {
msg("Successfully loaded %s\n", loadLibs[i]);
} else {
msg("Failed to load %s\n", loadLibs[i]);
}
}
}

char IDAP_comment[] = "DLL Auto-Loader";
char IDAP_help[] = "Loads the first 5 DLLs"
" mentioned in a binary file\n";

char IDAP_name[] = "DLL Auto-Loader";
char IDAP_hotkey[] = "Alt-D";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};




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

6.2 Liệt kê các hàm có chưa lệnh MOV
//
// movsfinder.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <allins.hpp>

int IDAP_init(void)
{
// Only support x86 architecture
if(strncmp(inf.procName, "metapc", 8) != 0) {
warning("Only x86 binary type supported, sorry.");
return PLUGIN_SKIP;
}

return PLUGIN_KEEP;
}

void IDAP_term(void)
{
return;
}

void IDAP_run(int arg)
{
// Instructions we're interested in. NN_movs covers movsd,
// movsw, etc.
int movinstrs[] = { NN_movsx, NN_movsd, NN_movs, 0 };

// Loop through all segments
for (int s = 0; s < get_segm_qty(); s++) {
segment_t *seg = getnseg(s);

// We are only interested in segments containing code.
if (seg->type == SEG_CODE) {
// Loop through each function
for (int x = 0; x < get_func_qty(); x++) {
func_t *f = getn_func(x);
char funcName[MAXSTR];

// Get the function name
get_func_name(f->startEA, funcName, sizeof(funcName)-1);
// Loop through the instructions in each function
for (ea_t addr = f->startEA; addr < f->endEA; addr++) {

// Get the flags for this address
flags_t flags = get_flags_novalue(addr);
// Only look at the address if it's a head byte, i.e.
// the start of an instruction and is code.
if (isHead(flags) && isCode(flags)) {
char mnem[MAXSTR];
// Fill the cmd structure with the disassembly of
// the current address and get the mnemonic text.
ua_mnem(addr, mnem, sizeof(mnem)-1);
// Check the mnemonic of the address against all
// mnemonics we're interested in.
for (int i = 0; movinstrs[i] != 0; i++) {
if (cmd.itype == movinstrs[i])
msg("%s: found %s at %a!\n", funcName, mnem, addr);
}
}
}
}
}
}

return;
}

char IDAP_comment[] = "MOVSx Instruction Finder";
char IDAP_help[] =
"Searches for all MOVS-like instructions.\n"
"\n"
"This will display a list of all functions along with\n"
"the movs instruction used within.";


char IDAP_name[] = "MOVSx Instruction Finder";
char IDAP_hotkey[] = "Alt-M";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};




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

6 Ví dụ
6.1 Tìm kiếm lời gọi đến các hàm sprintf, strcpy, và sscanf
//
// unsafefunc.cpp
//

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <lines.hpp>
#include <name.hpp>

int IDAP_init(void)
{
if(inf.filetype != f_ELF && inf.filetype != f_PE) {
warning("Executable format must be PE or ELF, sorry.");
return PLUGIN_SKIP;
}

return PLUGIN_KEEP;
}

void IDAP_term(void)
{
return;
}

void IDAP_run(int arg)
{
// The functions we're interested in. Names might need some
// re-adjustment depending on your platform.
char *funcs[] = { "sprintf", "strcpy", "sscanf", 0 };

// Loop through all segments
for (int i = 0; i < get_segm_qty(); i++) {
segment_t *seg = getnseg(i);

// We are only interested in the pseudo segment created by
// IDA, which is of type SEG_XTRN. This segment holds all
// function 'extern' definitions.
if (seg->type == SEG_XTRN) {

// Loop through each of the functions we're interested in.
for (int i = 0; funcs[i] != 0; i++) {
// Get the address of the function by its name
ea_t loc = get_name_ea(seg->startEA, funcs[i]);
// If the function was found, loop through it's
// referrers.
if (loc != BADADDR) {
msg("Finding callers to %s (%a)\n", funcs[i], loc);
xrefblk_t xb;
// Loop through all the TO xrefs to our function.
for (bool ok = xb.first_to(loc, XREF_DATA);
ok;
ok = xb.next_to()) {
// Get the instruction (as text) at that address.
char instr[MAXSTR];
char instr_clean[MAXSTR];
generate_disasm_line(xb.from, instr, sizeof(instr)-1);
// Remove the colour coding and format characters
tag_remove(instr, instr_clean, sizeof(instr_clean)-1);
msg("Caller to %s: %a [%s]\n",
funcs[i],
xb.from,
instr_clean);
}
}
}
}
}

return;

}

char IDAP_comment[] = "Insecure Function Finder";
char IDAP_help[] = "Searches for all instances"
" of strcpy(), sprintf() and sscanf().\n";


char IDAP_name[] = "Insecure Function Finder";
char IDAP_hotkey[] = "Alt-I";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};




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

5.19 Chuỗi
Những hàm sau đây được sử dụng để đọc danh sách chuỗi trong cửa sổ Strings của IDA, mà được dẫn xuất từ những chuỗi được thấy trong tập tin bị đảo mã hiện tại. Những hàm bên dưới được định nghĩa trong tập tin strlist.hpp.
5.19.1 refesh_strlist
Định nghĩa
idaman void ida export
refresh strlist(ea t eal, ea t ea2)
Chú giải
Làm tươi danh sách chuỗi trong cửa sổ Strings của IDA. Tìm kiếm giữa hai địa chỉ ea1 và ea2 trong tập tin bị đảo mã hiện tại.
Ví dụ
#include <strlist.hpp>
// Refresh the string list. refresh strlist();


5.19.2 get_strlist_qty
Định nghĩa
idaman size t ida export get strlist qty(void)
Chú giải
Returns the number of strings found in the currently disassembled file(s).
Trả về số lượng chuỗi được tìm thấy trong tập tin được đảo mã hiện tại.
Ví dụ
#include <strlist.hpp>
msg("%d strings were found in the currently open file(s)", get strlist qty());


5.19.3 get_strlist_item
Định nghĩa
idaman bool ida export
get strlist item(int n, string info t *si)
Chú giải
Điền vào *si thông tin về chuỗi thứ n. Trả về false nếu không có chuỗi có thứ tự n.
Ví dụ
#include <strlist.hpp> int largest = 0;
// Loop through all strings, finding the largest one. for (int i = 0; i < get strlist qty(); i++) { string info t si; get strlist item(i, &si); if (si.length > largest) largest = si.length;
}
msg("Largest string is %d characters long.\n", largest);


5.20 Misc
Những hàm sau đây không phù hợp với bất cứ danh mục nào. Tập tin tiêu đề mà chúng được định nghĩa được đề cập đến trong mỗi trường hợp.
5.20.1 tag_remove
Định nghĩa
idaman int ida export
tag remove(const char *instr, char *buf, int bufsize)
Chú giải
Loại bỏ bất cứ đánh dấu màu sắc nào trong chuỗi *instr, và lưu kết quả vào vùng nhớ *buf, được giới hạn bởi bufsize. Cung cấp con trỏ giống nhau cho *instr và *buf cũng được hỗ trợ, trong trường hợp này bufsize là 0. Hàm này được định nghĩa trong lines.hpp.
Ví dụ
#include <ua.hpp> // For ua functions #include <lines.hpp>
// Get the entry point address ea t addr = inf.startIP;
// Fill cmd with information about the instruction // at the entry point decode insn(addr);
// Loop through each operand (until one of o void type // is reached), displaying the operand text. for (int i = 0; cmd.Operands[i].type != o void; i++) { char op[MAXSTR]; _ ua outop(addr, op, sizeof(op)-1, i);
// Strip the colour tags off tag remove(op, op, 0); msg("Operand %d: %s\n", i, op);
}


5.20.2 open_url
Định nghĩa
inline void
open url(const char *url)
Chú giải
Mở đường dẫn *url trong trình duyệt web mặc định của hệ thống. Hàm này được định nghĩa trong kernwin.hpp.
Ví dụ
#include <kernwin.hpp>
open url("http://www.binarypool.com/idapluginwriting/");


5.20.3 call_system
Định nghĩa
idaman int ida export
call system(const char *command)
Chú giải
Chạy lệnh được truyền vào bởi chuỗi *command, từ dòng lệnh hệ thống. Hàm này được định nghĩa trong diskio.hpp.
Ví dụ
#include <diskio.hpp>
// Run notepad
call system("notepad.exe");


5.20.4 ida_dir
Định nghĩa
idaman const char *ida export idadir(const char *subdir)
Chú giải
Trả về đường dẫn của IDA nếu giá trị *subdir là NULL, nếu *subdir không NULL, thư mục con của IDA sẽ được trở về. Những thư mục con có thể được liệt kê được khai báo trong diskio.hpp.
#define CFG SUBDIR "cfg"
#define IDC SUBDIR "idc"
#define IDS SUBDIR "ids"
#define IDP SUBDIR "procs"
#define LDR SUBDIR "loaders"
#define SIG SUBDIR "sig"
#define TIL SUBDIR "til"
#define PLG SUBDIR "plugins"
Hàm này được định nghĩa trong diskio.hpp.
Ví dụ
#include <diskio.hpp>
msg("IDA directory is %s and your plug-in lives in %s.\n", idadir(NULL), idadir(PLG SUBDIR));


5.20.5 getdspace
Định nghĩa
idaman uint64 ida export getdspace(const char *path)
Chú giải
Trả về tổng dung lượng đĩa trong ổ dịa được đại diện bởi *path. Hàm này có thể được tìm thấy ở diskio.hpp
Ví dụ
#include <diskio.hpp>


5.20.6 str2ea
Định nghĩa
idaman bool ida export
str2ea(const char *str, ea t *ea ptr, ea t screenEA)
Chú giải
Chuyển một chuỗi *str thành địa chỉ và lưu nó vào con trỏ *ea nếu nó tồn tại trong tập tin bị đảo mã hiện tại, trả về true nếu thành công. Hàm này được định nghĩa trong kernwin.hpp.
Ví dụ
#include <kernwin.hpp>
// Just some random address char *addr s = "010100F0"; ea t addr;
// If 010100F0 is in the binary, print the address if (str2ea(addr s, &addr, 0))
msg("Address: %a\n", addr);


5.20.7 ea2str
Định nghĩa
idaman char *ida export
ea2str(ea t ea, char *buf, int bufsize)
Chú giải
Chuyển địa chỉ ea thành chuỗi, và lưu nó vào vùng đệm ký tự *buf, giới hạn bởi bufsize. Định dạng của chuỗi được kết xuất là tên đoạn : địa chỉ, ví dụ, cung cấp địa chỉ 0100102A từ đoạn .text sẽ cho ra .text:0100102A. Hàm này được định nghĩa trong kernwin.hpp.
Ví dụ
#include <kernwin.hpp>
ea t addr = get screen ea(); char addr s[MAXSTR]; _
// Convert addr into addr s ea2str(addr, addr s, sizeof(addr s)-1); msg("Address: %s\n", addr s);


5.20.8 get_nice_coloured_name
Định nghĩa
idaman ssize t ida export
get nice colored name(ea t ea, char *buf, size t bufsize, int flags=0);
Chú giải
Lấy tên được định dạng của địa chỉ ea, lưu nó vào vùng đệm ký tự *buf giới hạn bởi kích thước bufsize. Nếu cờ được đặt là GNCN_NOCOLOR, không có mã màu được thêm vào tên. Nếu địa chỉ ea không có tên, địa chỉ của nó sẽ được trả về dưới dạng “có thể đọc được”, như start + 56 hoặc .text:0100210. Hàm này được định nghĩa trong name.hpp.
Ví dụ
#include <kernwin.hpp> // For get screen ea() definition #include <name.hpp>
char buf[MAXSTR];
// Get the nicely formatted name/address of the // current cursor position. No colour codes will // be included.
get nice colored name(get screen ea(),
buf,
sizeof(buf)-1,
GNCN NOCOLOR);
msg("Name at cursor position: %s\n", buf);

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

5.17 Điểm dừng
Một phần thiết yếu của việc dò lỗi là khả năng đặt và thao tác với những điểm dừng, mà có thể được đặt ở bất kỳ địa chỉ nào trong không gian bộ nhớ của tiến trình và có thể là dạng cứng hoặc mềm. Những hàm sau đây làm việc với điểm dừng, và được định nghĩa trong dbg.hpp.
5.17.1 get_bpt_qty
Định nghĩa
int idaapi get bpt qty(void)
Chú giải
Trả về số lượng điểm dừng đang tồn tại (bao gồm cả những điểm dừng đang hoặc không được kích hoạt)
Ví dụ
#include <dbg.hpp>
msg("There are currently %d breakpoints set.\n", get_bpt_qty());


5.17.2 getn_bpt
Định nghĩa
bool idaapi
getn bpt(int n, bpt t *bpt)
Chú giải
Điền vào *bpt với thông tin về điểm dừng có vị trí n. Trả về false nếu không có điểm dừng nào có vị trí đó.
Ví dụ
#include <dbg.hpp>
// Go through all breakpoints, displaying the address // of where they are set.
for (int i = 0; i < get bpt qty(); i++) { bpt t bpt;
if (getn bpt(i, &bpt))
msg("Breakpoint found at %a\n", bpt.ea);
}


5.17.3 get_bpt
Định nghĩa
bool idaapi
get bpt(ea t ea, bpt t *bpt)
Chú giải
Điền vào bpt thông tin về điểm dừng được đặt tại địa chỉ ea. Nếu không có điểm dừng nào tại địa chỉ này, giá trị false được trả về. Nếu *bpt là NULL, hàm này đơn giản sẽ trả về true hoặc false tùy vào điểm dừng có được đặt tại địa chỉ ea hay không.
Ví dụ



5.17.4 add_bpt *
Định nghĩa
bool idaapi
add bpt(ea t ea, asize t size = 0, bpttype t type = BPT SOFT)
Chú giải
Thêm một điểm dừng tại địa chỉ ea với kiểu được xác định bởi type và kích cỡ được xác định bởi size. Trả về false nếu nó không thể đặt điểm dừng. Tham khảo phần 4.4.2 để được mô tả chi tiết về những kiểu điểm dừng khác nhau. Size không hợp lệ khi đặt một điểm dừng mềm.
Ví dụ
<dbg.hpp>
// Add a software breakpoint at the cursor position if (add bpt(get screen ea(), 0, BPT SOFT))
msg("Successfully set software breakpoint at %a\n", get screen ea());


5.17.5 del_bpt *
Định nghĩa
bool idaapi del bpt(ea t ea)
Chú giải
Xóa một điểm dừng được định nghĩa tại địa chỉ ea. Nếu không có điểm dừng nào được định nghĩa tại đó, giá trị false được trả về.
Ví dụ
#include <dbg.hpp>
// Go through all breakpoints, deleting each one. for (int i = 0; i < get bpt qty(); i++) { bpt t bpt;
if (getn bpt(i, &bpt)) {
// Because we are performing many delete // operations, queue the request, otherwise the // getn bpt call will fail when the id // numbers change after the delete operation.


5.17.6 update_bpt
Định nghĩa
bool idaapi
update bpt(const bpt t *bpt)
Chú giải
Cập nhạt những thành phần có thể sửa đổi của điểm dừng được đại diện bởi *bpt. Trả về false nếu sửa đổi không thành công.
Ví dụ
#include <dbg.hpp>
// Loop through all breakpoints for (int i = 0; i < get bpt qty(); i++) { bpt t bpt;
if (getn bpt(i, &bpt)) {
// Change the breakpoint to not pause // execution when it's hit bpt.flags A= BPT BRK;
// Change the breakpoint to a trace breakpoint bpt.flags |= BPT TRACE;
// Run a little IDC every time it's hit qstrncpy(bpt.condition,
"Message(\"Trace hit!\")", sizeof(bpt.condition));
// Update the breakpoint if (!update bpt(&bpt))
msg("Failed to update breakpoint at %a\n", bpt.ea);
}
}


5.17.7 enable_bpt *
Định nghĩa
bool idaapi
enable bpt(ea t ea, bool enable = true)
Chú giải
Kích hoạt hoặc vô hiệu hóa điểm dừng tại địa chỉ ea. Nếu không có điểm dừng nào được định nghĩa tại địa chỉ ea, hoặc có một lỗi xảy ra khi kích hoạt/ vô hiệu hóa điểm dừng, giá trị false được trả về. Nếu tham số enable được đặt thành false, điểm dừng vị vô hiệu.
Ví dụ
#include <kernwin.hpp> // For get screen ea() definition #include <dbg.hpp>
bpt t bpt;
// If a breakpoint exists at the user's cursor, disable // it.
if (get bpt(get screen ea(), &bpt)) {
if (enable bpt(get screen ea(), false)) msg("Disabled breakpoint.\n");
}


5.18 Dò
Những hàm sử dụng để dò chủ yếu tập trung vào việc kiểm tra một kiểu dò nào đó có được kích hoạt, đang được kích hoạt hoặc đang vị vô hiệu một kiểu dò nào đó và lấy những sự kiện dò. Tất cả các hàm bên dưới được định nghĩa trong dbg.hpp.
5.18.1 set_trace_size
Định nghĩa
bool idaapi
set trace size(int size)
Chú giải
Đặt bộ đệm dò bằng kích cỡ được cho bởi size. Trả về false nếu có lỗi xảy ra khi cấp phát kích cỡ này. Đặt kích cỡ bằng 0 sẽ thiết lập một vùng đệm có kích thước vô hạn (nguy hiểm). Nếu bạn đặt kích cỡ vùng đệm nhỏ hơn số lượng sự kiện dò, kích cỡ của sự kiện sẽ bị xóa.
Ví dụ
#include <dbg.hpp>
// 1000 trace events allowed if (set trace size(1000))
msg("Successfully set the trace buffer to 1000\n");


5.18.2 clear_trace *
Định nghĩa
void idaapi clear trace(void)
Chú giải
Xóa bộ đệm dò
Ví dụ
#include <dbg.hpp>


5.18.3 is_step_trace_enabled
Định nghĩa
bool idaapi
is step trace enabled(void)
Chú giải
Trả về đúng nếu dò theo bước đang được kích hoạt.
Ví dụ
#include <dbg.hpp>
if (is step trace enabled())
msg("Step tracing is enabled.\n");


5.18.4 enable_step_trace *
Định nghĩa
bool idaapi
enable step trace(int enable = true)
Chú giải
Kích hoạt dò theo bước. Nếu tham số enable được đặt thành false, dò theo bước sẽ bị vô hiệu.
Ví dụ
#include <dbg.hpp>
// Toggle step tracing if (is step trace enabled()) enable step trace(false);
else
enable step trace();


5.18.5 is_insn_trace_enabled
Định nghĩa
bool idaapi
is insn trace enabled(void)
Chú giải
Trả về true nếu dò tho chỉ thị đang được kích hoạt.
Ví dụ
#include <dbg.hpp>
if (is insn trace enabled())
msg("Instruction tracing is enabled.\n");


5.18.6 enable_insn_trace *
Định nghĩa
bool idaapi
enable insn trace(int enable = true)
Chú giải
Kích hoạt dò theo chỉ thị. Nếu tham số enable được gán bằng false, dò theo chỉ thị sẽ bị vô hiệu.
Ví dụ
#include <dbg.hpp>
// Toggle instruction tracing if (is insn trace enabled()) enable insn trace(false);
else
enable insn trace();


5.18.7 is_func_trace_enabled
Định nghĩa
bool idaapi
is func trace enabled(void)
Chú giải
Trả về true nếu chức năng dò theo hàm dược kích hoạt.
Ví dụ
#include <dbg.hpp>
if (is func trace enabled())
msg("Function tracing is enabled.\n");


5.18.8 enable_func_trace
Định nghĩa
bool idaapi
enable func trace(int enable = true)
Chú giải
Kích hoạt chức năng dò theo hàm. Nếu tham số enable được gán bằng false, dò theo hàm bị vô hiệu.
Ví dụ
#include <dbg.hpp>
// Toggle function tracing if (is func trace enabled()) enable func trace(false);
else
enable func trace();


5.18.9 get_tev_qty
Định nghĩa
int idaapi
get tev qty(void)
Chú giải
Trả về số lượng sự kiện dò đang được lưu trong bộ đệm dò.
Ví dụ
#include <dbg.hpp>
msg("There are %d trace events in the trace buffer.\n", get tev qty());


5.18.10 get_tev_info
Định nghĩa
bool idaapi
get tev info(int n, tev info t *tev info)
Chú giải
Trả về *tev thông tin về sự kiện dò trong bộ đệm dò ở vị trí thứ n. Trả về false nếu không có sự kiện dò nào ở vị trí n.
Ví dụ
#include <dbg.hpp>
// Loop through all trace events for (int i = 0; i < get tev qty(); i++) { tev info t tev;
// Get the trace event information get tev info(i, &tev);
// Display the address the event took place msg("Trace event occurred at %a\n", tev.ea);
}


5.18.11 get_insn_tev_reg_val
Định nghĩa
bool idaapi
get insn tev reg val(int n, const char *regname, regval t *regval)
Chú giải
Lưu giá trị của thanh ghi *regname vào biến *regval khi chỉ thị của sự kiện dò thứ n xảy ra, trước khi thực thi chỉ thị này. Trả về false nếu sự kiện không phải là một chỉ thị dò.
Lưu giá trị của thanh ghi *regname vào biến *regval khi chỉ thị dò
Ví dụ
#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);
// If it's an instruction trace event... if (tev.type == tev insn) {
// Get ESP, store into &esp
if (get insn tev reg val(i, "ESP", &esp))
// Display the value of ESP
msg("TEV #%d before exec: %a\n", i, esp.ival);
else
msg("No ESP change for TEV #%d\n", i);
}
}


5.18.12 get_insn_tev_reg_result
Định nghĩa
bool idaapi
get insn tev reg result(int n, const char *regname, regval t *regval)
Chú giải
Lưu giá trị của thanh ghi *regname vào biến *regval khi chỉ thị dò thứ n xảy ra, sau khi thực thi chỉ thị này. Trả về false nếu thanh ghi không bị thay đổi hoặc n không phải là một chỉ thị dò.
Ví dụ
#include <dbg.hpp>


5.18.13 get_call_tev_callee
Định nghĩa
ea t idaapi
get call tev callee(int n)
Chú giải
Trả về địa chỉ của hàm được gọi cho hàm sự kiện dò thứ n. Trả về BADADDR nếu không có hàm dò nào thứ n. Kiểu của hàm sự kiện dò phải là tev_call.
Ví dụ
#include <dbg.hpp>
// Loop through all trace events for (int i = o; i < get tev qty(); i++) { regval_t esp; tev info t tev;
// Get the trace event information get tev info(i, &tev);
// If it's an function call trace event... if (tev.type == tev call) { ea t addr;
// Get ESP, store into &esp
if ((addr = get call tev callee(i)) != BADADDR) msg("Function at %a was called\n", addr);
}
}


5.18.14
Định nghĩa
ea t idaapi
get ret tev return(int n)
Chú giải
Trả về địa chỉ của hàm gọi đến hàm dò sự kiện thứ n. Trả về BADADDR nếu không có hàm dò sự kiện thứ n nào. Kiểu của hàm sự kiện dò phải là tev_ret
Ví dụ
#include <dbg.hpp>
// Loop through all trace events for (int i = 0; i < get tev qty(); i++) { tev info t tev;
// Get the trace event information get tev info(i, &tev);
// If it's an function return trace event... if (tev.type == tev ret) { ea t addr;
if ((addr = get ret tev return(i)) != BADADDR) msg("Function returned to %a\n", addr);
}
}


5.18.15
Định nghĩa
ea t idaapi
get bpt tev ea(int n)
Chú giải
Trả về địa chỉ của sự kiện dò thứ n có kiểu đọc/ghi/thực thi. Trả về false nếu không có sự kiện dò nào thuộc loại đọc/ghi/thực thi.
Ví dụ
#include <dbg.hpp>
// Loop through all trace events for (int i = 0; i < get tev qty(); i++) { tev info t tev;
// Get the trace event information get tev info(i, &tev);
// If it's an breakpoint trace event... if (tev.type == tev bpt) { ea t addr;
if ((addr = get bpt tev ea(i)) != BADADDR)
msg("Breakpoint trace hit at %a\n", addr);
}
}