函数原代码

原代码  时间:2021-03-17  阅读:()
火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cnIDAProAppcall功能浅析By:obaby其实IDA的这个功能应该出现的比较早了,最早应该是在IDAPro5.
6中出现的,但是在国内一直没有看到这方面的相关文章.
也不知道国内有没有人留意这些者脚本直接调用内置的函数没有明显的区别.
如果你使用过GDB调试器(Call命令)、VS(Immediate窗口)或者BorlandC++Builder等你应该对于这个功能比较熟悉了.
上面的截图显示了如何使用IDC语法调用了三个函数:printf,MessageBoxA和GetDesktopWindow.
在深入之前,请首先明白一点,本文只是一个简单的介绍,更全面的文章将在后面介绍.
快速开始在开始之前首先要明白使用IDC命令调用Appcall的时候所接受的参数.
上面的函数可以通过下面的简单代码进行调用:火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cn就像你看到的那样我们直接引用Appcall函数_prinft就像它是内置的IDC函数一样.
如果你的函数名称中存在在IDC语法中不能用作标记函数名称的字符或者函数名称存在重复,如下图所示:则可以通过下面的IDC语法来调用Appcall:我们使用LocByName函数通过传入函数的名称来获取函数的地址(该地址是可以被调用的).
上面的代码同样可以通过下面的多行代码来实现同样的效果:automyfunc=LocByName("_my_func@8");myfunc("hello","world");需要注意Appcall只在当前进程空间中有效,如果你想在另外的一个进程中执行,那么首先要切换到目标进程中.
Appcall和IDCAppcall机制可以通过下面的函数在IDC中进行调用://Callapplicationfunction//ea-addresstocall//type-typeofthefunctiontocall.
canbespecifiedas://-declarationstring.
example:"intfunc(void);"//-typeinfoobject.
example:GetTinfo(ea)//-zero:thetypewillberetrievedfromtheidbargumentsofthefunctiontocall//Returns:theresultofthefunctioncall//Ifthecallfailsbecauseofanaccessviolationorotherexception,//aruntimeerrorwillbegenerated(itcanbecaughtwithtry/catch)火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cn//Infactthereisrarelyanyneedtocallthisfunctionexplicitly.
//IDCtriestoresolveanyunknownfunctionnameusingtheapplicationlabels//andinthecaseofsuccess,willcallthefunction.
Forexample://_printf("hello\n")//willcalltheapplicationfunction_printfprovidedthatthereis//noIDCfunctionwiththesamename.
anyvalueAppcall(ea,type,.
.
.
);AppcallIDC函数需要你传递一个函数的地址,函数类型信息和参数(如果有).
autop=LocByName("_printf");autoret=Appcall(p,GetTinfo(p),"Hello%s\n","world");现在我们已经知道如何来调用一个已经知道函数类型的函数,现在假设有另外的一个函数我们不知道函数类型以及参数类型:在使用Appcall()调用这个函数之前,我们首先需要知道函数类型信息(保存在一个类型信息结构中),autop=ParseType("long__stdcallFindWindow(constchar*cls,constchar*wndname)",0);Appcall(LocByName("user32_FindWindowA"),p,0,"Untitled-Notepad");在这里我们使用ParseType()函数来构建一个类型信息结构体来传递给Appcall()函数,然而永久的设定一个函数的原型也是可能的,因而可以通过下面的代码来设定一个函数的原型:SetType(LocByName("user32_FindWindowA"),"long__stdcallFindWindow(constchar*cls,onstchar*wndname)");通过引用传递参数(Passingargumentsbyreference)为了通过引用传递参数,只需要使用C语言中的&符号进行即可.
例如调用下面的函数:voidref1(int*a){if(a==NULL)return;into=*a;intn=o+1;*a=n;火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cnprintf("calledwith%dandreturning%d\n",o,n);}我们可以在IDC中使用下面的代码实现:autoa=5;Message("a=%d",a);ref1(&a);Message(",afterthecall=%d\n",a);调用一个携带了一个字符串参数并且进行修改的函数:/*Ccode*/intref2(char*buf){if(buf==NULL)return-1;printf("calledwith:%s\n",buf);char*p=buf+strlen(buf);*p+*p='\0';printf("returnedwith:%s\n",buf);intn=0;for(;p!
=buf;p--)n+=*p;returnn;}我们需要创建一个缓冲区并且将它传递给被调用的函数,因为代码如下所示:autos=strfill('\x00',20);//createabufferof20characterss[0:5]="hello";//initializethebufferref2(&s);//callthefunctionandpassthestringbyreferenceif(s[5]Message("notdot\n");elseMessage("dot\n");__usercall调用约定Appcall函数可能没有一个标准的调用约定,例如由汇编语言编写的子函数可能需要通过各种寄存器来传递参数等等.
一种方法是通过_usercall调用约定来描述你的函数:参考如下的函数原型:/*Ccode*///eax=esi-ediint__declspec(naked)asm1()火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cn{__asm{moveax,esisubeax,ediret}}从IDC函数中调用将会是下面的代码:autop=ParseType("int__usercallasm1(inta,intb);",0);autor=Appcall(LocByName("_asm1"),p,5,2);Message("Theresultis:%d\n",r);不定参数函数(Variableargumentfunctions)C代码:intva_altsum(intn1,.
.
.
){va_listva;va_start(va,n1);intr=n1;intalt=1;while((n1=va_arg(va,int))!
=0){r+=n1*alt;alt*=-1;}va_end(va);returnr;}IDC代码:autoresult=va_altsum(5,4,2,1,6,9,0);调用函数可能引发异常在使用Appcall的过程中可能会触发异常.
为了捕获这些异常你可以在IDC程序中使用try/catch结构:autoe;try{AppCall(some_func_addr,func_type,arg1,arg2);//Orequally:火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cn//some_func_name(arg1,arg2);}catch(e){//Exceptionoccured.
.
.
.
.
}异常结构"e"将会包含如下的数据区段:描述(description):在调试器执行Appcall的过程中产生的异常描述信息;函数(func):发生异常的IDC函数的名称;行号(line):在脚本程序中发生错误行的行号;错误编号(qerrno):最后一个错误的内部编号.
例如你可能会得到如下的信息:description:"Appcall:Theinstructionat0x401F93referencedmemoryat0x5.
Thememorycouldnotberead"file:""func:"___idc0"line:4qerrno:92在一些条件下异常结构有可能会包含更多的信息.
Appcall选项简介Appcall可以功过SetAppcallOptions()函数进行设置,该函数包含如下的选项:APPCALL_MANUAL:仅设置Appcall而不运行(在完成之后你需要调用CleanupAppcall()函数).
可以通过ManualAppcall章节来获取更多信息;APPCALL_DEBEV:如果该标志位被设置,那么在执行appcall的过程中如果有异常产生则会包含异常的全部信息.
可以通过不过调试异常章节来得到更多的信息.
在实际的过程中可以比较方便的恢复Appcall的默认设置,你可以修改它们,然后在把他们修改回来.
为了恢复设置只需要简单的调用GetAppcallOptions()函数即可.
需要注意Appcall选项是保存在数据库中的,所以一旦你修改了他们,当再次运行的时候Appcall选项将会自动恢复ManualAppcall到这里我们已经看到了如何来调用Appcall并且使用脚本来获取执行后的结果,那么如果我们只是想设置环境并且向手工执行函数该怎么办火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cn此时就要用到ManualAppcall功能了.
ManualAppcall架构可以用来保存当前执行代码的上下文,然后在另外的空间中执行另外的一个函数.
在执行完成之后我们可以返回到原来的进程空间并且继续从刚才保存的地点继续调试.
让我们以现实中的需求来说明这个功能的意义:1.
你正在调试你的程序2.
你发现了一个存在bug的函数(foo()),当传入特定的参数的时候这个函数会表现的十分怪异foo(0xdeadbeef)3.
那么我们此时是不是应该继续等待一个特殊的参数来继续触发这个问题函数其实没有必要那么复杂,我们只需要手工调用foo函数并且传入特定参数进行跟踪即可.
4.
最后,在执行完成之后只需要执行CleanupAppcall()来恢复手工调用appcall之前异常的内容即可为了验证效果我们以上文中提到的ref1函数来进行试验,我们只需要传入一个非法的指针即可:1.
SetAppcallOptions(APPCALL_MANUAL);//SetmanualAppcallmode2.
ref1(6);//callthefunctionwithaninvalidpointer在执行完上面的代码之后IDA将会转换到调用的函数,到这里我们就可以进行调试了.
在执行到函数末尾的时候代码如下:在执行到函数返回之后我们很可能会看到如下的代码:这是我们用来检测Appcall函数末尾的控制代码.
到这里我们就可以调用CleanupAppcall()来返回到上一次执行的上下文空间了.
火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cn捕获调试异常在上文中我们已经可以捕获Appcall调用过程中的异常,但是如果我们想要知道操作系统原生的异常信息这些是远远不够的.
如果我们多多少少的能够从调试器模块中获取到最后的debug_event_t指令就更好了.
APPCALL_DEBEV选项使得我们的想法成为可能.
我们通过APPCALL_DEBEV选项再次来重复上面的例子:autoe;try{SetAppcallOptions(APPCALL_DEBEV);//Enabledebugeventcapturingref1(6);}catch(e){//Exceptionoccured.
Thistime"e"ispopulatedwithdebug_event_tfields(checkidd.
hpp)}在这种情况下,如果我们转存异常结构信息,我们将会得到下面的属性:can_cont:1code:C0000005hea:401F93heid:40h(fromidd.
hpp:EXCEPTION=0x00000040Exception)file:""func:"___idc0"handled:1info:"Theinstructionat0x401F93referencedmemoryat0x6.
Thememorycouldnotberead"line:4hpid:123Chref:6htid:1164hAppcall和PythonAppcall的概念和IDC与Python基本是一致的,然而Appcall/Python有着不同的语法,(不同的引用,宽字符等等).
火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cnAppcall构架是由idaapi模块提供的,调用一个Appcall:Appcall.
printf("Helloworld!
\n");同样可以创建一个Appcall函数的引用并且直接调用:printf=Appcall.
printf#.
.
.
later.
.
.
printf("Helloworld!
\n");如果你的函数包含在Python中不能用作名称的字符或者存在冲突那么可以通过下面的代码进行调用:findclose=Appcall["__imp__FindClose@4"]getlasterror=Appcall["__imp__GetLastError@0"]setcurdir=Appcall["__imp__SetCurrentDirectoryA@4"]如果你想重新定义已经存在的函数的定义则可以通过调用Appcall.
proto(func_name、func_ea、prototype_string)来实现:#passanaddressnameandAppcall.
proto()willresolveitloadlib=Appcall.
proto("__imp__LoadLibraryA@4","int(__stdcall*LoadLibraryA)(constchar*lpLibFileName);")#PassanEAinsteadofanamefreelib=Appcall.
proto(LocByName("__imp__FreeLibrary@4"),"int(__stdcall*FreeLibrary)(inthLibModule);")为了传递Unicode字符串你需要用到Appcall.
unicode()函数:getmodulehandlew=Appcall.
proto("__imp__GetModuleHandleW@4","int(__stdcall*GetModuleHandleW)(LPCWSTRlpModuleName);")hmod=getmodulehandlew(Appcall.
unicode("kernel32.
dll"))定义一个函数然后关联到一个地址你同样可以得到一个Appcall:#Createatypedobject(noaddressisassociatedyet)virtualalloc=Appcall.
typedobj("int__stdcallVirtualAlloc(intlpAddress,SIZE_TdwSize,DWORDflAllocationType,DWORDflProtect);")#Laterwehaveanaddress,sowepassit:virtualalloc.
ea=LocByName("kernel32_VirtualAlloc")#NowwecanAppcall:ptr=virtualalloc(0,Appcall.
Consts.
MEM_COMMIT,0x1000,Appcall.
Consts.
PAGE_EXECUTE_READWRITE)在我们得出结论之前(如果你已经认真的读过上面的内容),这里提供了一个小脚本,它可以用来初始化和终止Appcall通过快捷键.
如果你想每次都让脚本自动加载那么就将这个脚本写入到idc\ida.
idc文件中即可:#includeexternlast_cmd,last_opt;火星信息安全研究院By:obabyhttp://www.
h4ck.
org.
cnstaticAppcall_Here(){last_opt=GetAppcallOptions();SetAppcallOptions(APPCALL_MANUAL);autot,h;t=ParseType("voidx(void);",0);h=here;Appcall(FirstSeg(),t);SetAppcallOptions(last_opt);Eip=h;}staticAppcall_Start(){autos=AskStr(last_cmd,"EnterAppcall");if(s=="")return;last_cmd=s;last_opt=GetAppcallOptions();SetAppcallOptions(APPCALL_MANUAL);Message(">%s原代码处.
Appcall能做的事情远比在本文中提到的要多的多,写这篇文章主要是想抛砖引玉,如果大家有什么好的技术还希望能一起交流,欢迎评论.

百纵科技:美国独立服务器租用/高配置;E52670/32G内存/512G SSD/4IP/50M带宽,999元/月

百纵科技怎么样?百纵科技国人商家,ISP ICP 电信增值许可证的正规公司,近期上线美国C3机房洛杉矶独立服务器,大带宽/高配置多ip站群服务器。百纵科技拥有专业技术售后团队,机器支持自动化,自助安装系统 重启,开机交付时间 30分钟内交付!美国洛杉矶高防服务器配置特点: 硬件配置高 线路稳定 洛杉矶C3机房等级T4 平价销售,支持免费测试,美国独服适合做站,满意付款。点击进入:百纵科技官方网站地...

BeerVM1GB内存/VDSps端口1GB,350元/月

beervm是一家国人商家,主要提供国内KVM VPS,有河南移动、广州移动等。现在预售湖南长沙联通vds,性价比高。湖南长沙vps(长沙vds),1GB内存/7GB SSD空间/10TB流量/1Gbps端口/独立IP/KVM,350元/月,有需要的可以关注一下。Beervm长沙联通vps套餐:长沙联通1G青春版(预售)长沙联通3G标准版(预售)长沙联通3G(预售)vCPU:1vCPU:2vCPU...

OneTechCloud(31元),美国CN2 GIA高防VPS月

OneTechCloud发布了本月促销信息,全场VPS主机月付9折,季付8折,优惠后香港VPS月付25.2元起,美国CN2 GIA线路高防VPS月付31.5元起。这是一家2019年成立的国人主机商,提供VPS主机和独立服务器租用,产品数据中心包括美国洛杉矶和中国香港,Cera的机器,VPS基于KVM架构,采用SSD硬盘,其中美国洛杉矶回程CN2 GIA,可选高防。下面列出部分套餐配置信息。美国CN...

原代码为你推荐
留学生认证留学生服务中心认证内容和范围?lunwenjiance我写的论文,检测相似度是21.63%,删掉参考文献后就只有6.3%,这是为什么?蒋存祺蒋存祺的主要事迹百度关键词工具常见的关键词挖掘工具有哪些www.yahoo.com.hk香港的常用网站www.zhiboba.com上什么网看哪个电视台直播NBAbaqizi.cc徐悲鸿到其中一张很美的女人体画66smsm.comffff66com手机可以观看视频吗?www.175qq.com请帮我设计个网名www.147.qqq.comWWW147EEE.COM这个网站现在改哪个网址了
香港主机租用 日本私人vps vmsnap3 52测评网 微信收钱 softbank邮箱 泉州电信 t云 华为云服务登录 中国电信测速器 中国电信测速网站 photobucket 江苏徐州移动 云销售系统 asp空间 闪讯网 香港博客 512内存 新网dns ncp是什么 更多