2021-08-29

参考雁过前辈的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 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值