参考雁过前辈的OD-插件-修正版,od-myInfo-断点/注释/标签
原插件存在一些BUG,当前已经修正,并且设定为自动化的
此插件解决某些不定地址的模块在换地址后断点注释消失的问题
其他需要的依赖项请去原作者的网页下载哈
全部源码如下:
//
// MyInfo Plugin for Ollydbg
// flyinghearts <flyinghearts@qq.com>
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation;
//
// label/comment file format:
// L/C address name
// L/C: label/Comment
//
// break point file format (.bp file):
// B "fn" A/R address E/D passcount comment S condition S expression S explanation S plugcmd N
//
// B: break point
// fn: filename
// A/R: the follow address is Absolute/Relative address
// E/D: Enable/Disable
// S: '\x1e' (you could change Sep defined below)
// N: "\x1e\n"
// passcount/condition/expression/explanation/plugcmd:
// see: Conditional logging breakpoint dialog (Shift+F4)
// Notice: There are two characters, '\x1e' and a space/tab, between each.
//
// example:
// B "abc.exe" A 00402253 E 0
// B "abc.dll" R 0000108A D 0
// B "test.exe" A 00402265 E 0 This is a comment.
// B "test.exe" A 0040227F E 0 a comment eax == 0
//
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "plugin.h"
#ifdef _MSC_VER
#pragma comment(lib,"OLLYDBG.LIB")
#define snprintf _snprintf
#define strnicmp _strnicmp
#endif
#define Cache_size 256
//Modify the following values to change default behaviour
#define BP_EXT ".bp" //break points
#define LC_EXT ".txt" //Label/Comment
//delimeter used in functions for importing/exporting breakpoints,
//don't change it to a space/tab.
#define Sep "\x1e"
void copy_labels_to_comment();
int export_name(FILE* fp);
void import_name();
void delete_extra_comment();
void import_bp();
void export_bp();
void delete_all_bps();
HINSTANCE hinst;
HWND hwmain;
char* ___ob = NULL;//[4096] = {0};
int ___obLen = 0;
char ___ot[128];
int inited = 0;
BOOL WINAPI DllEntryPoint(HINSTANCE hi,DWORD reason,LPVOID reserved)
{
if (DLL_PROCESS_ATTACH == reason)
hinst = hi;
return 1;
}
extc int _export cdecl ODBG_Plugindata(char shortname[32])
{
strncpy(shortname,"MyInfo", 32);
return PLUGIN_VERSION;
}
extc int _export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw,ulong *features)
{
if (ollydbgversion < PLUGIN_VERSION)
return -1;
hwmain = hw;
Addtolist(0,0, "MyInfo plugin v1.2 by flyinghearts");
return 0;
}
extc void _export cdecl ODBG_Pluginsaveudd(t_module *pmod,int ismainmodule)
{
if(ismainmodule)
{
export_bp();
inited = 0;
//sprintf(___ot,"ODBG_Pluginsaveudd \r\n");
//MessageBox(hwmain,___ot,"调用",MB_OK);
}
}
//extc void _export cdecl ODBG_Pluginreset(void)
//{
// import_bp();
//sprintf(___ot,"ODBG_Pluginreset \r\n");
//MessageBox(hwmain,___ot,"调用",MB_OK);
//}
extc int _export cdecl ODBG_Paused(int reason,t_reg *reg)
{
if(inited == 0 && reason == PP_EVENT)
{
inited = 1;
import_bp();
//sprintf(___ot,"ODBG_Paused reason = %x\r\n",reason);
//MessageBox(hwmain,___ot,"调用",MB_OK);
}
return 0;
}
/*
extc int _export cdecl ODBG_Pluginmenu(int origin,char data[4096],void *item)
{
switch (origin)
{
case PM_MAIN:
strncpy(data,"1 &1 复制标签到注释|"
"2 &2 导出标签|"
"3 &3 导出注释|"
"4 &4 导入标签/注释|"
"5 &5 删除当前模块非代码段内的注释|"
"7 &7 导出断点信息|"
"8 &8 导入断点信息|"
"9 &9 删除所有断点|"
"0 &0 关于", 4096
);
return 1;
case PM_BREAKPOINTS:
if (Plugingetvalue(VAL_MAINBASE) == 0)
return 0;
strncpy(data, "#MyInfo {"
"1 &1 导出断点信息|"
"2 &2 导入断点信息|"
"3 &3 删除所有断点"
"}",
4096);
return 1;
default: break;
}
return 0;
}
extc void _export cdecl ODBG_Pluginaction(int origin,int action,void *item)
{
if (PM_MAIN == origin)
{
switch (action)
{
case 1: copy_labels_to_comment(); break; //copy labels to comments
case 2: export_name(); break; //export labels
case 3: export_name(); break; //export comments
case 4: import_name(); break;
case 5: delete_extra_comment(); break;
case 7: export_bp(); break;
case 8: import_bp(); break;
case 9: delete_all_bps(); break;
case 0: MessageBox(hwmain, "MyInfo plugin v1.2 "
"\n by flyinghearts (flyinghearts@qq.com)\n\n",
"About",MB_OK|MB_ICONINFORMATION);
break;
default: break;
}
}
else if(PM_BREAKPOINTS == origin)
{
switch (action)
{
case 1: export_bp(); break;
case 2: import_bp(); break;
case 3: delete_all_bps(); break;
default: break;
}
}
}
*/
void getRealAddr(ulong* _addr,ulong* _base,char* _module_name)
{
int i,n;
ulong addr = *_addr;// - *_base;
ulong base = *_base;
char* module_name;
t_table* table = (t_table*)Plugingetvalue(VAL_MODULES);
t_module* module_s = (t_module*) Getsortedbyselection(&(table->data), 0);
if (table == NULL || (n = table->data.n) == 0)
{
*_addr = 0;
*_base = 0;
return;
}
for (i = 0; i < n; i++,module_s++)
{
//base = module_s->base;
module_name = strrchr(module_s->path,'\\');
module_name = module_name == NULL ? module_s->path : module_name + 1;
if(_module_name && module_name && strcmp(_module_name,module_name) == 0)
{
//sprintf(___ot,"base:addr = 0x%X:0x%X",base,addr);
//MessageBox(hwmain, ___ot,"取址结果",MB_OK);
addr -= base;
//sprintf(___ot,"addr -= base = 0x%X",addr);
//MessageBox(hwmain, ___ot,"取址结果",MB_OK);
addr += module_s->base;
//sprintf(___ot,"[%s->%s]0x%X:0x%X -> 0x%X:0x%X",_module_name,module_name,*_base,*_addr,module_s->base,addr);
//MessageBox(hwmain, ___ot,"取址结果",MB_OK);
*_addr = addr;
*_base = base;
return;
}
//sprintf(___ot,"C %08lX %08lX %c %lX \"%s\" %s %s %s %s\n",addr,base,nametype,0,module_name,name,"nil","nil","nil");
//fprintf(fp,"B \"%s\" %c %08lX %c %lX %s\n",module_name,addr_type,addr,bp_type,passcount,comment);
//strcat(___ob,___ot);
}
//___obLen = strlen(___ob);
//MessageBox(hwmain, ___ob,"结果",MB_OK);
*_addr = 0;
*_base = 0;
return;
}
int export_name(FILE* fp)
{
int i,n;
int count = 0;
ulong addr,base;
char* module_name;
char name[TEXTLEN];
struct t_module *module;
t_table* table = (t_table*)Plugingetvalue(VAL_MODULES);
t_module* module_s = (t_module*) Getsortedbyselection(&(table->data), 0);
if (table == NULL || (n = table->data.n) == 0)
return -1;
base = module_s->base;
Findname(base-1,NM_LABEL,name);
while ((addr = Findnextname(name)) != 0)
{
module = Findmodule(addr);
//base = module_s->base;
module_name = strrchr(module->path,'\\');
module_name = module_name == NULL ? module->path : module_name + 1;
fprintf(fp,"L %08lX %08lX %c %lX \"%s\" \"%s\" %s %s %s \r\n",addr,module->base,NM_LABEL,0,module_name,name,"nil","nil","nil");
//sprintf(___ot,"L %08lX %08lX %c %lX \"%s\" %s %s %s %s\n",addr,module->base,NM_LABEL,0,module_name,name,"nil","nil","nil");
//fprintf(fp,"B \"%s\" %c %08lX %c %lX %s\n",module_name,addr_type,addr,bp_type,passcount,comment);
//strcat(___ob,___ot);
++count;
}
Findname(base-1,NM_COMMENT,name);
while ((addr = Findnextname(name)) != 0)
{
module = Findmodule(addr);
//base = module_s->base;
module_name = strrchr(module->path,'\\');
module_name = module_name == NULL ? module->path : module_name + 1;
fprintf(fp,"C %08lX %08lX %c %lX \"%s\" \"%s\" %s %s %s \r\n",addr,module->base,NM_COMMENT,0,module_name,name,"nil","nil","nil");
//sprintf(___ot,"C %08lX %08lX %c %lX \"%s\" %s %s %s %s\n",addr,module->base,NM_COMMENT,0,module_name,name,"nil","nil","nil");
//fprintf(fp,"B \"%s\" %c %08lX %c %lX %s\n",module_name,addr_type,addr,bp_type,passcount,comment);
//strcat(___ob,___ot);
++count;
}
//___obLen = strlen(___ob);
//MessageBox(hwmain, ___ob,"结果",MB_OK);
return count;
}
void export_bp()
{
char filename[MAX_PATH];
char name[TEXTLEN];
char expr[TEXTLEN];
char expl[TEXTLEN];
char plugcmd[TEXTLEN];
//char result[Cache_size];
char bp_type,addr_type;
char *module_name;
ulong type,addr,passcount,main_base,base;
int i,s,n,count,namecount, total;
FILE *fp;
t_table *table;
t_module *module;
t_bpoint *bp;
//filename[0] = 0;
//if (Browsefilename("导入断点信息\n",filename,BP_EXT,0)== 0)
// return;
//MessageBox(hwmain, "export_bp","结果",MB_OK);
main_base = Plugingetvalue(VAL_MAINBASE);
if (main_base == 0)
return;
module = (t_module*) Findmodule(main_base);
module_name = strrchr(module->path,'\\');
module_name = module_name == NULL ? module->path : module_name + 1;
sprintf(filename,"PLUGIN\\断点信息-%s.txt",module_name);
if ((fp = fopen(filename, "wb")) == NULL)
{
MessageBox(hwmain, "无法打开文件!","失败",MB_OK);
return;
}
table = (t_table*)Plugingetvalue(VAL_BREAKPOINTS);
if (table == NULL || (n = table->data.n) ==0 )
return;
//___ob[0] = 0;
bp = (t_bpoint*)Getsortedbyselection(&(table->data), 0);
for (i = 0, count = 0; i < n; i++,bp++)
{
addr = bp->addr;
type = bp->type;
if ((TY_INVALID | TY_ONESHOT | TY_TEMP) & type)
continue;
//If TY_ACTIVE and TY_DISABLED are set simultaneously,TY_DISABLED is ignored
if (type & TY_ACTIVE) bp_type = 'E';
else if(type & TY_DISABLED) bp_type = 'D';
else continue;
passcount = bp->passcount;
//bp++;
if ((module = Findmodule(addr)) == 0) continue;
base = module->base;
Findname(addr,NM_BREAK,name);
Findname(addr,NM_BREAKEXPR,expr);
Findname(addr,NM_BREAKEXPL,expl);
Findname(addr,NM_PLUGCMD,plugcmd);
module_name = strrchr(module->path,'\\');
module_name = module_name == NULL ? module->path : module_name + 1;
if(!name[0])sprintf(name,"nil");
if(!expr[0])sprintf(expr,"nil");
if(!expl[0])sprintf(expl,"nil");
if(!plugcmd[0])sprintf(plugcmd,"nil");
++count;
fprintf(fp,"B %08lX %08lX %c %lX \"%s\" \"%s\" %s %s %s \r\n",addr,base,bp_type,passcount,module_name,name,expr,expl,plugcmd);
//sprintf(___ot,"B %08lX %08lX %c %lX \"%s\" %s %s %s %s \n",addr,base,bp_type,passcount,module_name,name,expr,expl,plugcmd);
//fprintf(fp,"B \"%s\" %c %08lX %c %lX %s\n",module_name,addr_type,addr,bp_type,passcount,comment);
//strcat(___ob,___ot);
}
//snprintf(result,1024,"n = %d,共导出%d个断点。\n\n%s",n,count,___ob);
//MessageBox(hwmain, result,"结果",MB_OK);
namecount = export_name(fp);
//___obLen = strlen(___ob);
//MessageBox(hwmain, ___ob,"结果",MB_OK);
fflush(fp);
fclose(fp);
//snprintf(name,256,"n = %d\r\n共导出%d个断点.\r\n共导出%d个标签\n\n",n,count,namecount);
//MessageBox(hwmain, name,"结果",MB_OK);
}
void import_bp()
{
char filename[MAX_PATH+1];
char name[TEXTLEN+1];
char expr[TEXTLEN+1];
char expl[TEXTLEN+1];
char comment[TEXTLEN+1];
char plugcmd[TEXTLEN+1];
char result[Cache_size];
char bp_type[2];
char ___bp_type;
char addr_type[2];
char newline[2];
char *module_name;
char ___module_name[TEXTLEN];
char *main_name;
char *prev_name;
ulong type,addr,passcount,main_base,main_end,prev_base,main_size,prev_size;
int ret,count,i,n;
BOOL check_main_name = 1;
FILE *fp;
t_table *table;
t_module *module, *module_s;
char * p = NULL;//___ob;
ulong base;
char insertFor = 0;
//MessageBox(hwmain, "import_bp","结果",MB_OK);
main_base = Plugingetvalue(VAL_MAINBASE);
if (main_base == 0)
return;
module = (t_module*) Findmodule(main_base);
module_name = strrchr(module->path,'\\');
module_name = module_name == NULL ? module->path : module_name + 1;
sprintf(filename,"PLUGIN\\断点信息-%s.txt",module_name);
if ((fp = fopen(filename, "rb")) == NULL)
{
//MessageBox(hwmain, "无法打开文件!","失败",MB_OK);
return;
}
fseek(fp,0,SEEK_END);
___obLen = ftell(fp);
fseek(fp,0,SEEK_SET);
___ob = malloc(___obLen + 1);
if (___ob == NULL)
{
MessageBox(hwmain, "分配读取配置的内存失败!","失败",MB_OK);
return;
}
if(fread(___ob,1,___obLen,fp) == -1)
{
MessageBox(hwmain, "读取配置!","失败",MB_OK);
return;
}
//sprintf(___ot,"读取字节:%d\r\n",___obLen);
//MessageBox(hwmain, ___ot,"成功",MB_OK);
//MessageBox(hwmain, ___ob,"读入信息",MB_OK);
___ob[___obLen] = 0;
p = ___ob;
main_base = Plugingetvalue(VAL_MAINBASE);
if (main_base == 0)
return;
module = (t_module*) Findmodule(main_base);
main_size = module->size;
main_end = main_base + main_size;
main_name = strrchr(module->path,'\\');
main_name = main_name == NULL ? module->path : main_name + 1;
prev_name = main_name;
prev_base = main_base;
prev_size = main_size;
table = (t_table*)Plugingetvalue(VAL_MODULES);
module_s = (t_module*) Getsortedbyselection(&(table->data), 0);
if (table == NULL || (n = table->data.n) == 0)
return;
count = 0;
while (1)
{
//There is a space/tab before the name/expr/expl/comment/plugcmd. Ignore it.
name[1] = expr[1] = expl[1] = comment[1] = plugcmd[1] = 0;
passcount = 0;
addr = 0;
if(p - ___ob >= ___obLen - 5)
break;
sscanf(p,"%c %lX %lX %c %lX %*c%[^\"]%*c %*c%[^\"]%*c %s %s %s",&insertFor,&addr,&base,bp_type,&passcount,___module_name,name,expr,expl,plugcmd);
if(strcmp(name,"nil") == 0)name[0] = 0;
if(strcmp(expr,"nil") == 0)expr[0] = 0;
if(strcmp(expl,"nil") == 0)expl[0] = 0;
if(strcmp(plugcmd,"nil") == 0)plugcmd[0] = 0;
while(p && *p && *p != '\n' )++p;
++p;
getRealAddr(&addr,&base,___module_name);
if(insertFor == 'B')
{
type = ('E' == bp_type[0]) ? (TY_ACTIVE | TY_KEEPCOND) : (TY_DISABLED | TY_KEEPCOND);
Setbreakpointext(addr,type,0,passcount);
//Quickinsertname(addr,NM_BREAK, name + 1);
//Quickinsertname(addr,NM_BREAKEXPR, expr + 1);
//Quickinsertname(addr,NM_BREAKEXPL, expl + 1);
//Quickinsertname(addr,NM_PLUGCMD, plugcmd + 1);
//Quickinsertname(addr,NM_COMMENT, comment + 1);
Quickinsertname(addr,NM_BREAK, name);
Quickinsertname(addr,NM_BREAKEXPR, expr);
Quickinsertname(addr,NM_BREAKEXPL, expl);
Quickinsertname(addr,NM_PLUGCMD, plugcmd);
}
else if(insertFor == 'L')
{
if (Quickinsertname(addr, NM_LABEL, name) == -1)
{
snprintf(result,Cache_size,"无法在地址%lX处插入标签/注释!\n",addr);
MessageBox(hwmain, result, "失败", MB_OK);
continue;
}
}
else if(insertFor == 'C')
{
if (Quickinsertname(addr, NM_COMMENT, name) == -1)
{
snprintf(result,Cache_size,"无法在地址%lX处插入标签/注释!\n",addr);
MessageBox(hwmain, result, "失败", MB_OK);
continue;
}
}
++count;
}
fclose(fp);
free(___ob);
___ob = NULL;
Mergequicknames();
Broadcast(WM_USER_CHALL,0,0);
//snprintf(result,Cache_size, "共设置了%d个断点\n\n", count);
//MessageBox(hwmain, result,"结果",MB_OK);
}
作者: flyinghearts
出处: http://www.cnblogs.com/flyinghearts/
本文采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。