首页
社区
课程
招聘
新增了olly脚本命令隐藏OD可见窗口到系统托盘
发表于: 2008-4-12 18:16 8613

新增了olly脚本命令隐藏OD可见窗口到系统托盘

2008-4-12 18:16
8613

【题目】新增帮助数据分析的olly脚本命令
【作者】无名氏 realzjx@hotmail.com
【目的】多年以来以来都是看帖不回帖,自己从网络上得到了很多,却从未曾回报。本帖的目的是为了有所回报,并且能够继续心安理得的潜水若干年。 本人才疏学浅, 脱,破,逆的水平都稀疏平常, 另外也没有足够的动机和时间去从事突破性的研究,高手们总结的都很好了。 我无意去挑战破解领域,只能发个本人改造的olly 脚本插件上来。 对我来讲有些用处,如果大家也觉得有点儿用,那我就达到目的了。
【声明】第一次发帖,希望不会被淹没。源码中有一些奇怪的注释和函数名, 那是从很久以前我做过的一个程序中抄来的,懒的修改了。代码以看雪工具上下载的ODbgScript工程为基础,加入了MFC的支持。 增加了4个脚本函数400多行代码。 用了几个小时的时间而已, 因此没有充分测试过。其中hide 和show是我测试过了的。 剩下两个没有测试过, 不过应该差不多能用吧。
【内容】
对我来讲,脱壳和反跟踪被突破以后的任务就是分析数据了。这时候通常的解决方法是编写一个dll注入到目标程序中帮助我们截获数据后进行分析。 但是这种方法工作量相对大一些,灵活性不够好, 而且不具有通用性。 因此我开发了这4个新的脚本函数。 我不喜欢贴一堆代码出来, 大家可以直接看附件,里面也有编译好的文件可以直接使用。 这里只介绍一下4个函数的功能,并且试着描述一下可能的应用场景。
hide  隐藏od窗口, 隐藏后桌面右下角系统托盘上会出现OD的小图标. 双击该图标, OD被唤出来。
show 显示od窗口, 并且删除系统托盘的图标。
sleep 休眠若干毫秒。
wrt2m 将被调试的进程的一段内存数据写入到一个共享内存队列中。

【应用1】使olly脚本成为隐形的补丁。
脚本执行中会遇到中断,中断发生的时候OD窗口被激活, 被调试进程的窗口失去焦点。 这样会严重影响我们对目标程序的操作和数据分析。调用hide隐藏OD可见窗口后, olly脚本就成为了真正的隐形补丁, 丝毫不影响我们对目标程序的使用。
【应用2】相信有些人会进行封包分析, 那么在hide后, 在关键的调用点中断后,脚本调用wrt2m 将数据写入共享内存, 自己再编写一个数据分析程序将共享内存中的数据导出来, 这样就不需要你在去hook目标进程了。 而且非常灵活,通用。
【应用3】在处理虚拟机的脚本中, 由于某些地方是解密后执行的, 基本上不可能直接补这些地方,只能是下硬件执行断点,执行到那里后再去用脚本处理, 这时候通常我们不需要OD窗口蹦出来骚扰我们的, 可以用hide命令把OD藏起来, 脚本中需要OD出来的地方调用show显示之。

【举例】下面的一个脚本就是一个隐形的内存补丁
hide //隐藏OD窗口
loop:  //循环保证地址47A183处的数据为0
BPHWS 47A183,"w"
sti
mov [47A183],0
jmp loop

wrt2m需要有一个对相同共享内存读取的接收程序配合使用
在接收程序中, 你需要加入完全相同的代码,调用pop函数对共享内存进行读取操作。 并且在使用前要先设置“SHAREMEM_EVENT”事件。

#define MEM_BLOCK_NUMBER 4
#define MEM_BLOCK_SIZE 20000
HANDLE g_hMutex=CreateMutex(NULL, FALSE, "SHAREMEM_MUTEX");//»¥³â·ÃÎÊ¡£
HANDLE g_hEvent=CreateEvent(NULL, TRUE, FALSE, "SHAREMEM_EVENT"); //ÓÉÊý¾Ý·ÖÎö³ÌÐòÉèÖá£Í¨ÖªÐ´ÈëÏíÄÚ´æÖС£
HANDLE g_hReadyEvent=CreateEvent(NULL, TRUE, FALSE, "HOOKREADY_EVENT"); //ÓÉÊý¾Ý·ÖÎö³ÌÐòÉèÖá£Í¨ÖªÐ´ÈëÏíÄÚ´æÖС£
typedef struct SMSG_MEM {
        int nBlock;        //Óм¸¸öÄÚ´æ¿é
        int iHead;
        int iTail;
        unsigned char * m_Buffer;
        SMSG_MEM()
        {
                nBlock = MEM_BLOCK_NUMBER;
        };
        BOOL Push(unsigned char * Buff, int size)
        {
                DWORD dwRet = WaitForSingleObject(g_hEvent,0);
                if(dwRet != WAIT_OBJECT_0)
                {
                        //µ±·â°ü·ÖÎö³ÌÐò×¼±¸¿ªÊ¼²¶»ñÒÔºóÔÙPushÊý¾Ý½øÈ¥¡£
                        return false;
                }
                while(1)
                {
                        dwRet = WaitForSingleObject(g_hMutex,INFINITE);
                        if(dwRet != WAIT_OBJECT_0)
                        {
                                return false;
                        }
                        if(iHead != (iTail+1)%MEM_BLOCK_NUMBER)
                        {
                                char * pDest = (char *)(this)+0x10;
                                memcpy(&pDest[iTail*MEM_BLOCK_SIZE],&size,sizeof(int));
                                memcpy(&pDest[iTail*MEM_BLOCK_SIZE+sizeof(int)],Buff,size);
                                iTail++;
                                iTail = iTail%MEM_BLOCK_NUMBER;
                                ReleaseMutex(g_hMutex);
                                break;
                        }
                        else
                        {
                                ReleaseMutex(g_hMutex);
                        }
                }
                //»¥³âÇø£¬ È¡³öͷβָÕëµÄÐÅÏ¢¡£
                //Èç¹û¶ÓÁÐΪ¿ÕÔòµÈ´ý2ºÁÃëÖØÐÂÈ¡
                return true;
        };
        BOOL Pop(unsigned char *Buff, int &size)
        {
                DWORD dwRet = WaitForSingleObject(g_hEvent,0);
                if(dwRet != WAIT_OBJECT_0)
                {
                        //µ±·â°ü·ÖÎö³ÌÐò×¼±¸¿ªÊ¼²¶»ñÒÔºóÔÙPushÊý¾Ý½øÈ¥¡£
                        return false;
                }
                while(1)
                {
                        dwRet = WaitForSingleObject(g_hMutex,INFINITE);
                        if(dwRet != WAIT_OBJECT_0)
                        {
                                return false;
                        }
                        if(iHead != iTail)
                        {
                                char * pDest = (char *)(this)+0x10;
                                memcpy(&size,&pDest[iHead*MEM_BLOCK_SIZE],sizeof(int));
                                memcpy(Buff,&pDest[iHead*MEM_BLOCK_SIZE+sizeof(int)],size);
                                iHead++;
                                iHead = iHead%MEM_BLOCK_NUMBER;
                                ReleaseMutex(g_hMutex);
                                break;
                        }
                        else
                        {
                                ReleaseMutex(g_hMutex);
                        }
                }
                //»¥³âÇø£¬ È¡³öͷβָÕëµÄÐÅÏ¢¡£
                //Èç¹û¶ÓÁÐΪ¿ÕÔòµÈ´ý2ºÁÃëÖØÐÂÈ¡
                return true;
        };
} * PMSG_MEM;
PMSG_MEM g_MessageMem;
HANDLE g_MessageMap;
BOOL g_InitShareMem()
{
        g_MessageMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,MEM_BLOCK_SIZE*MEM_BLOCK_NUMBER+200 ,"ZJXSHARE_SMSSTR");
        g_MessageMem = (PMSG_MEM)MapViewOfFile(g_MessageMap,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
        if(g_MessageMem ==NULL)
                return FALSE;
        g_MessageMem->nBlock=MEM_BLOCK_NUMBER;
        g_MessageMem->iHead=0;
        g_MessageMem->iTail=0;
        //g_MessageMem->m_Buffer=(unsigned char *)((DWORD)g_MessageMem+sizeof(SMSG_MEM));
        SetEvent(g_hReadyEvent);
        return TRUE;
}
以上以附件代码中的内容为准
重新修改了一下那个没有初始化的bug, 另外测了一下wrt2m下面是新的link, 昨天晚上已经和我的数据处理程序联调,调通了。 并且fix几个bug。 汗啊, 以为没有bug,结果还是fix了两个, 对不住抢先下载的兄弟们了。这已经是第三个下载连接了。 由于
这次把4个都彻底测了一遍。 以后我就不再更新了。

http://rapidshare.de/files/39102697/ollyscript.zip.html


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不好意思, wrt2m 没有测试, 果然是有问题的。 忘记初始化了。 修改代码贴到这里了。
大家看看代码就清楚了, 可以更好的消化吸收一下。有Bug就帮改改。

bool OllyLang::Dowrt2m(string args)
{
        BOOL bRet=TRUE;
        string ops[3];
       
        if(!CreateOperands(args, ops, 3))
                return false;
        static bInit=FALSE;
        if(!bInit)
        {
                g_InitShareMem();
        }
2008-4-12 19:28
0
雪    币: 87
活跃值: (47)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
3
顶下。多谢。
2008-4-12 22:45
0
雪    币: 228
活跃值: (25)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
严重支持楼主
2008-4-13 11:06
0
雪    币: 47147
活跃值: (20380)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
5
感谢realzjx!
为了方便,我将文件转到本地。
2008-4-13 12:15
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
前面下载的兄弟,还得麻烦多下载一次。 我把sleep和wrt2m都联调测试过了, fix两个Bug, 因此正文中, 这两个函数后的(没有测试)的提示我也去掉了。 文中的链接是最新的代码。 应该不会动了。 文章中增加的【应用3】实际上也是近几天我对这个函数的应用。
昨天联调完毕后, 个人认为wrt2m还是很有用的。省的你去写DLL去hook人家的程序了
2008-4-13 14:23
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
7
谢谢~很实用的功能
建议增加延时脚本命令(虽然也有变通的方法),这样可以允许在一定的准备工作完成后针对某些屏幕刷新操作下断,形如:

hide
sleep(5000)
bp Bitblt

等等
2008-4-13 14:37
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
增加延时脚本命令 会稍微麻烦点。 一下子想不出什么好的解决方案。 乍一想 可以把脚本pause了, 然后可开个thread, 到点就把target pause了, 线程推出, 脚本再继续运行。
2008-4-14 16:49
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
9
ms确实需要开一个线程来通知的样子。。
2008-4-14 19:53
0
雪    币: 59
活跃值: (1481)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
顶下。多谢。
2008-4-17 12:00
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
好东东先收下, 谢谢!
2008-4-21 15:06
0
雪    币: 211
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
顶下。多谢。
2008-5-2 00:54
0
游客
登录 | 注册 方可回帖
返回
//