使用免费工具进行逆向和利用:第18部分

admin 2022年4月15日10:42:38使用免费工具进行逆向和利用:第18部分已关闭评论82 views字数 3572阅读11分54秒阅读模式

原作者:Ricardo Narvaja

翻译作者:梦幻的彼岸

更新日期:2022年1月21日


好吧,为了在逆向和继续深入的主题和练习之前暂停一下,让我们看看本例中脚本主题,例如为IDA FREE编写脚本。

我们都知道IDA PRO包括IDA PYTHON,能够在IDA中制作脚本,我们没有这种可能性,但利用我们所拥有的优势,这已经足够了,IDA FREE支持用IDC制作脚本,这是一种C语言,但这是为了能够为IDA FREE和PRO制作脚本。

IDC脚本编写

我们可以通过菜单选项FILE-SCRIPT FILE来运行我们写在idc文件中的脚本。

下面还有IDC栏,您可以在这里执行单个命令,或者几个用分号分隔的命令。

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

很明显,这不是一个很舒服的工具栏,但我们有第三个选择来测试小代码块。

使用免费工具进行逆向和利用:第18部分

好吧,让我们开始吧,IDC中可以使用的函数列表在IDA的帮助文档中。

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

我们可以看到,它有很多功能,有些是在调试时使用的,有些可以在不调试时使用,它有很多的可能性。

好吧,让我们看看IDC语言的“几乎是“casi C”是什么样子的,呵呵。

其中一个主要的区别是,它不是一种必须声明类型的语言,这里的通用类型是 "auto",适用于脚本中所有局部变量的情况。

使用免费工具进行逆向和利用:第18部分

我们看到每个变量可以包含什么,用 "extern "声明的全局变量,其他的就不多说了,显然这是一种非常简单的语言,只适用于脚本编写。

除了文档中所说的,在文本编辑器中打开idc.idc文件也很有用,该文件位于:

C:\Program Files\IDA Freeware 7.0\idc

使用免费工具进行逆向和利用:第18部分

它有idc列表中没有的功能,在help中有很多帮助。

我们将了解并执行一些函数,进入IDC。

为了测试和使用相同的可执行文件,我们将使用上一个64位练习。

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

我们看到MinEa()函数返回我们加载的第一个部分的开始,在本例中是代码部分,因为默认情况下不加载头。

如果我用MANUAL LOAD重新加载可执行文件,覆盖以前的数据库,并接受它加载所有的部分,包括头,在这种情况下,MinEa()将返回基地址...

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

通过VIEW-OPEN SUBVIEWS-SEGMENTS,我们可以看到加载的部分。

使用免费工具进行逆向和利用:第18部分

当然,使用MaxEA()我们将看到最后加载的部分的末尾.

使用免费工具进行逆向和利用:第18部分

在没有头的情况下重新装载。

使用免费工具进行逆向和利用:第18部分

我们看到,它总是显示最低加载部分的开始和最后最高加载部分的结束。

使用免费工具进行逆向和利用:第18部分

ScreenEa() 向我们显示光标所在的地址。

使用免费工具进行逆向和利用:第18部分

它们是相似的,但我们必须传递一个地址,并返回它们对应的部分的开始和结束,它可以连接到找出光标所在的部分的开始和结束。

使用免费工具进行逆向和利用:第18部分

搜索GADGET的脚本

好吧,我们要慢慢做一个自制的脚本,在代码部分寻找一些gadge或说明。

当然,当我们查找文本时,我们只会发现指令对齐并被IDA检测为指令的结果。除了代码之外,我们将无法在其他部分找到未对齐的指令,但为了练习,在一些快速案例中,很少有指令会起作用。

对于它们,我们将使用FindText(),它可以使用REGEX搜索指令。

使用免费工具进行逆向和利用:第18部分

当我们查找文本时,例如,如果我们查找“POP RBX”,我将找不到上面显示的结果,因为它有多个空格,应该用相同数量的空格写出完全相同的结果。

我发现它找不到它。

使用免费工具进行逆向和利用:第18部分

相反,在使用REGEX搜索的标记之间添加选项。

使用免费工具进行逆向和利用:第18部分

然后,我可以使用星号,它允许我匹配星号之前的一个或多个字符。

使用免费工具进行逆向和利用:第18部分

该搜索将找到POP EBX、POP EBX、POP EBX、POP EBX,无论POP和EBX之间有多少个空格,都会匹配。

我怎样才能找到我想要的最多10条指令,我将在小窗口中进行。

使用免费工具进行逆向和利用:第18部分

我找到了一个地址,我用类似printf的Message函数打印它。

我看到我把局部变量ea声明为auto,而且我没有忘记在每条指令的末尾加上分号。

现在我想打印10我将做一个循环。

使用免费工具进行逆向和利用:第18部分

所以它总是找到同一个我必须在找到一个之后增加搜索地址,以便它接下来搜索。

使用免费工具进行逆向和利用:第18部分

当然,你必须把MInEA()从循环中拿出来,否则它总是从那里开始搜索,并使用一个递增的变量,我使用ea,每次找到后我把它递增1,这样它就从下一个字节开始搜索,不会从同一个地方重复搜索。

我看到我找到了10条指令,我看看其他一些指令。

嗯,我们做得很好。

使用免费工具进行逆向和利用:第18部分

接下来要做的是打印你找到的指令,但首先我将添加这个检查:

if (ea == BADADDR){break;}

也就是说,如果ea=-1 就意味着他什么都没找到。

使用免费工具进行逆向和利用:第18部分

有了这个,我不仅可以搜索到10个,而且可以搜索到所有的。

使用免费工具进行逆向和利用:第18部分

搜索,直到它返回-1,因为它可以找到很多。

使用免费工具进行逆向和利用:第18部分

我们缺少打印find语句,使用Get Disasm()将其作为字符串返回给我,使用Message将其打印为格式化字符串。

使用免费工具进行逆向和利用:第18部分

我们正在改进,嘿嘿。

使用免费工具进行逆向和利用:第18部分

将要搜索的字符串放在开头很方便,甚至可以要求用窗口键入,以便用户输入要搜索的内容。

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

也许我现在不会添加它,让字符串放在变量中。

任何喜欢它的人都可以这样做。

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

我们看到,它以同样的方式运作。

使用免费工具进行逆向和利用:第18部分

我将再添加一个字符串。

使用免费工具进行逆向和利用:第18部分

从找到第一个的地址,我将寻找第二个的地址,我将在两者之间设置一个最大距离 ,如果距离小于这个最大距离,我就接受它,否则不接受...

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

我将第一个匹配的地址存储在基数中,并从第一个字符串中寻找第二个字符串,因为ea有第一个字符串的地址。

如果它从第一个字符串中找到第二个字符串,我必须检查它们之间的距离。

使用免费工具进行逆向和利用:第18部分

我们可以看到,有些我只打印了POP r14,而没有打印POP RSI,而在其他情况下,我发现两者都有,我将把打印移到最后,这样它只在发现两者时打印。

使用免费工具进行逆向和利用:第18部分

我把所有的信息放在下面,这样它只在两个字符串都存在时才会打印出来。

现在的问题是,如果我们看到有时两者之间有中间指令,因为它们之间可能有6条指令的距离,那么打印中间指令就好了。

对于他们,我们将使用该指令。

NextHead(base,end_addr);

这样我就得到了当前指令的下一条指令的地址。

使用免费工具进行逆向和利用:第18部分

使用免费工具进行逆向和利用:第18部分

然后我把它拿到NOTEPAD++上,对准了一点,以避免在按键上弄得一团糟。

使用免费工具进行逆向和利用:第18部分

现在我缺的是输出条件,只要它能打印出来,否则就一直打印到无穷大。

使用免费工具进行逆向和利用:第18部分

现在它打印了两条指令之间的所有中间指令。

现在我要在 ret 中添加 gadget 的最大长度

auto max_gadget=10; //maximo largo del gadget

使用免费工具进行逆向和利用:第18部分

然后我还必须从基数中搜索一个 ret,即从它找到的第一个匹配项开始。

使用免费工具进行逆向和利用:第18部分

添加base3,从string retn的base进行搜索,并将地址保存在base3中。

使用免费工具进行逆向和利用:第18部分

也就是说,现在的条件是两个语句之间的距离小于distance,并且与base之间的距离小于max_gadget。

现在我们必须让它打印到BASE2,而不是BASE3,也就是RET。

使用免费工具进行逆向和利用:第18部分

还不错,呵呵,你可以放大看更多的说明,这里最重要的是练习,我把脚本留在这里。

最终脚本

include // For User defined functions

static main()

{
auto ea,i,base,base2,base3,dis,dis2,stri,stri2,distance,max_gadget;
stri="pop r14";
stri2="pop
rsi";
distance=6; //mxima distancia entre instrucciones
max_gadget=10; //maximo largo del gadget
ea=MinEA();
while (1)

{

       ea=FindText(ea, SEARCH_DOWN|SEARCH_NEXT|SEARCH_REGEX, 0, 0, stri);
       if (ea == BADADDR){break;}
       dis = GetDisasm(ea);                                                     
       base=ea;
       ea=FindText(ea, SEARCH_DOWN|SEARCH_NEXT|SEARCH_REGEX, 0, 0, stri2);
       if (ea == BADADDR){break;}
       base2=ea;              
       ea=FindText(base, SEARCH_DOWN|SEARCH_NEXT|SEARCH_REGEX, 0, 0, "retn");
       if (ea == BADADDR){break;}
       base3=ea;
       if ((base2-base)<= distance && (base3-base)<= max_gadget)

       {
                Message("0%x",base);
                Message(" %s -",(dis));
                while(1)
                {
                ea=NextHead(base,MaxEA());
                dis2 = GetDisasm(ea);
                Message(" %s -",(dis2));
                base = ea;
                      if (base>=base3){
                      Message(" \n\n");
                      break;}
                }
       }

ea++;
}

}

当然,如果您不想丢失它,您可以将其导出,并把它保存在一个文件中,然后随时从菜单上运行。

我认为这是一个很好的想法,可以练习,改进这个脚本,增加更多的东西,这是一个基础,可以在IDC中获得一些乐趣,它并不像外面所描绘的那样可怕。

至第19部分。

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月15日10:42:38
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   使用免费工具进行逆向和利用:第18部分http://cn-sec.com/archives/913071.html