作 者: menting 时 间: 2008-02-20,18:07 链 接: http://bbs.pediy.com/showthread.php?t=59933今天来了,看到很热闹,我也热闹一下,大家春节过的好不好??,实际,今天带给大家的比较麻烦,不容易 理解,比起以往的来讲都要难点了,但是,相对很容易了,我是自己一点点反复的试中学习过来的,今天发出来给喜欢 逆向的朋友,我觉得逆向比我想的要复杂,而切是件耐心的磨性子的事,强烈建议没耐心的就别折腾了。反正我是领教 了。 在看这篇时大家需要有心理准备,就是汇编与C++的关系,要对C++和汇编都要很熟悉才可以,不然,很难理解 的,还有就是IDA和OD是不可少的,最好有WinHex和UE,我们要在IDA和OD中间寻找我们的答案。所以,在学习的时候大 家可以选择一些简单的程序,最好不大的,几十KB到几KB的程序,方便逆向。现在逆向的人不多,我想想学的人不会也 不多的。只是苦于没有这类书籍,记得有本什么黑客反汇编的书,是个老外写的还不错,大家有兴趣可以找找。 我这里说的不一定都是准确的,我只是将我的测试结果发出来,高手们要指点一二哦!我是个超级菜鸟,呵呵 ~~~,希望别惹大家笑话,喜欢的就学习了,不喜欢的就看个乐子吧! 注意:在逆向的程序选择时,新手最好选择基本的C代码的程序,不建议选择pascal 和basic的代码,这些代码 不容易理解,而且和汇编的关系不是很明确的。逆向的时候选择C的代码,我发现很容易和汇编联系的。但是要将汇编反 过来写成C语言那就又是麻烦了。:(! 这里不建议选择MFC类程序,只建议大家选择Win32程序,这样我们的难度就小了很 多了,还有个就是不建议选择类程序,初学的时候就最好是函数、变量、指针。等学的差不多了,再加进去类和结构等 等。 //------------------------------------------------------------ 第一部分 常量、变量 //------------------------------------------------------------ 在逆向的时候我们可以自己写点程序,来研究的,但是我推荐Visual C++ 6.0 ,为什么是6.0呢?因为2003以 后程序被编译以后不再像6.0那样的清晰,编译器给程序加了很多垃圾进去,不太好分析。在编译的时候使用Release, 这样代码量会小,花的工夫就相对来说少很多。 我们把下面的代码编译进程序,看起来很简单的。但是结果是不一样的,所有教C语言的老师都说下面的代码结 果是一样的,但是,我发现在汇编里就不一定的哦!!很奇怪吧,大家可以自己多试试,我这里所说的都是常规状态下 的。 第一、局部变量: //------------------------------------------- int intbuf1=1,intbuf2=2; int intbuf3=3; int intbuf4=4; //------------------------------------------- OD反汇编以后的结果和下面的差不多的,有朋友会问了,为什么我的就没有下面的代码,只有一个retn 好像什么都没做 哦,在你的变量没做任何事时,只对其进行初试化,那么编译器在Release模式下,是不被解释的。我们在设置的C/C++ 选项中,将Maximize Speed改为Default,这个时候我们就能看到了汇编代码。 //------------------------------------------- 0040135F /___FCKpd___0nbsp; 55 push ebp 00401360 |. 8BEC mov ebp, esp 00401362 |. 83EC 10 sub esp, 10 00401365 |. C745 F8 01000>mov dword ptr [ebp-8], 1 0040136C |. C745 FC 02000>mov dword ptr [ebp-4], 2 00401373 |. C745 F0 03000>mov dword ptr [ebp-10], 3 0040137A |. C745 F4 04000>mov dword ptr [ebp-C], 4 00401381 |. 8BE5 mov esp, ebp 00401383 |. 5D pop ebp 00401384 /. C3 retn //------------------------------------------- 我们不难分析出栈顺序intbuf2-intbuf1-intbuf4-intbuf3,我不说了,大家自己思考编译器是如果解释变量的,而我们 需要注意的是dword ptr [ebp-X],我们把例子改一下: //------------------------------------------- BYTE intbuf1=1; char intbuf2=2; int intbuf3=3; DWORD intbuf4=4; LONG intbuf5=5; SHORT intbuf6=6; WORD intbuf7=7; //------------------------------------------- 不难从下面的代码中我们可以看出,char和BYTE都对应byte ptr,SHORT和WORD都对应word ptr,LONG和DWORD都对应 dword ptr,我们就很容易分辨出源代码的类型了,简单吧,现在看到如下的汇编代码就容易理解和明白了,我想谁都可 以把它写成C代码或者其他语言的代码了。 //------------------------------------------- 0040135F /___FCKpd___0nbsp; 55 push ebp 00401360 |. 8BEC mov ebp, esp 00401362 |. 83EC 1C sub esp, 1C 00401365 |. C645 F8 01 mov byte ptr [ebp-8], 1 00401369 |. C645 FC 02 mov byte ptr [ebp-4], 2 0040136D |. C745 F0 03000>mov dword ptr [ebp-10], 3 00401374 |. C745 F4 04000>mov dword ptr [ebp-C], 4 0040137B |. C745 E8 05000>mov dword ptr [ebp-18], 5 00401382 |. 66:C745 EC 06>mov word ptr [ebp-14], 6 00401388 |. 66:C745 E4 07>mov word ptr [ebp-1C], 7 0040138E |. 8BE5 mov esp, ebp 00401390 |. 5D pop ebp 00401391 /. C3 retn //------------------------------------------- 前面我们说了,定义地方不同在汇编中也是不同的,还有变量的类型我们先来看这样一段汇编代码,大家可以猜写出它 的C语言代码^_^ //-------------------------------------------- 0040135F /___FCKpd___0nbsp; 55 push ebp 00401360 |. 8BEC mov ebp, esp 00401362 |. 83EC 0C sub esp, 0C 00401365 |. C745 F8 01000>mov dword ptr [ebp-8], 1 0040136C |. 8B45 F8 mov eax, dword ptr [ebp-8] 0040136F |. 8945 FC mov dword ptr [ebp-4], eax 00401372 |. 8B4D FC mov ecx, dword ptr [ebp-4] 00401375 |. 034D F8 add ecx, dword ptr [ebp-8] 00401378 |. 894D F8 mov dword ptr [ebp-8], ecx 0040137B |. 8B55 F8 mov edx, dword ptr [ebp-8] 0040137E |. 0355 FC add edx, dword ptr [ebp-4] 00401381 |. 8955 F4 mov dword ptr [ebp-C], edx 00401384 |. 8BE5 mov esp, ebp 00401386 |. 5D pop ebp 00401387 /. C3 retn //-------------------------------------------- 看了会不会头大了,呵呵~~~,是不是有点不同了,看看我怎么逆吧~~ //-------------------------------------------- DWORD unk1=1; //mov dword ptr [ebp-8], 1 DWORD unk2=unk1; //mov eax, dword ptr [ebp-8] //mov dword ptr [ebp-4], eax //我们发现在第2句里多了个ebp-4所以我们就能确定了,有新的变量出现了,而且是DWORD类型的,EAX把变量unk1的 内//容传递到了新的变量中。 unk1=unk2+unk1; //mov ecx, dword ptr [ebp-4] //add ecx, dword ptr [ebp-8] //mov dword ptr [ebp-8], ecx //我们知道先取出unk2的值放入ecx,我们可以看到在相加后又放回了unk1; unk3=unk1+unk2; //mov edx, dword ptr [ebp-8] //add edx, dword ptr [ebp-4] //mov dword ptr [ebp-C], edx //我想我不用解释大家一看就明白了吧~~~~ //---------------------------------------------------------- 源代码如下: int intbuf1=1; int intbuf2=intbuf1; intbuf1=intbuf2+intbuf1; int intbuf3=intbuf1+intbuf2; //---------------------------------------------------------- 是不是一句都没错哦~~,我是逆了好多了,所以一看就知道了,大家在练习的时候多试试,就会发现规律的, 不是老师们说的,代码一但编译就不可能复原了,那是不准确的,可以做到几乎接近。 第二、全局变量: 代码为下面: //---------------------------------------------------------- BYTE intbuf1=0; char intbuf2=0; int intbuf3=0; DWORD intbuf4=0; LONG intbuf5=0; SHORT intbuf6=0; WORD intbuf7=0; void InitMain() { intbuf1=1; intbuf2=2; intbuf3=3; intbuf4=4; intbuf5=5; intbuf6=6; intbuf7=7; } //---------------------------------------------------------- 汇编如下: //---------------------------------------------------------- 0040135F /___FCKpd___0nbsp; 55 push ebp 00401360 |. 8BEC mov ebp, esp 00401362 |. C605 74854000>mov byte ptr [408574], 1 00401369 |. C605 75854000>mov byte ptr [408575], 2 00401370 |. C705 78854000>mov dword ptr [408578], 3 0040137A |. C705 7C854000>mov dword ptr [40857C], 4 00401384 |. C705 80854000>mov dword ptr [408580], 5 0040138E |. 66:C705 84854>mov word ptr [408584], 6 00401397 |. 66:C705 86854>mov word ptr [408586], 7 004013A0 |. 5D pop ebp 004013A1 /. C3 retn //------------------------------------------------------------ ^_^,大家在逆向的时候会发现了把,全局变量和局部变量的区别了吧~~~,我想大家一看就明白了,局部变量是放在栈中 的,而全局变量是不放的,还有就是其它和局部变量都一样的,但是我们需要注意,指针问题,有的时候指针和变量是 一样的,不太好分辨,以后我会再给大家解释。 第三、常量 代码如下: //------------------------------------------------------------ #define test2 2 #define test3 "123456789" void InitMain() { int mm=test2; char *pcc=test3; } //需要说明的是,我们用#define做的宏函数在编译的时候,是被直接编译出结果的,根据宏函数来确定是镶嵌代码还是 //直接编译结果。 //------------------------------------------------------------- 反汇编后,发现变量和指针是基本一样的,没什么明显的区别,是变量还是指针,大家多练习就是了,不是简单的说就 是什么就什么,实际指针在汇编中是以变量的形式来处理的,我们在汇编中就把指针当变量,但是在逆回到C语言中时我 们必须对其进行区分的。可以很明确的看出常量在汇编中什么怎么样处理的,我们把它逆回去不是很简单的事了吗? //------------------------------------------------------------- 0040135F /___FCKpd___0nbsp; 55 push ebp 00401360 |. 8BEC mov ebp, esp 00401362 |. 83EC 08 sub esp, 8 00401365 |. C745 FC 02000>mov dword ptr [ebp-4], 2 0040136C |. C745 F8 30604>mov dword ptr [ebp-8], 00406030 ; ASCII "123456789" 00401373 |. 8BE5 mov esp, ebp 00401375 |. 5D pop ebp 00401376 /. C3 retn //---------------------------------------------------------------- 逆向是件不容易的事,我已经给大家很简单的示范了,想想实际没什么的,是没什么,简单,但是真的做起来就不容易 了,大家可以再多试试,就会发现,代码和汇编之间是有本质的联系的。我们可以逆出很接近原代码的代码来。 第四、实践练手 只说不练,被说成那个什么假什么把势的,好,我们就来练习一下。我想大家要是把这段代码看明白了,一定 会猜到我下次要给大家带来什么了,郁闷不??说的很简单,练起手来还蛮难^_^。 //---------------------------------------------------------------- 0040128D /___FCKpd___0nbsp; 55 push ebp 0040128E |. 8BEC mov ebp, esp 00401290 |. 81EC 0C010000 sub esp, 10C 00401296 |. 57 push edi 00401297 |. 8D85 F8FEFFFF lea eax, dword ptr [ebp-108] 0040129D |. 50 push eax 0040129E |. E8 860E0000 call 00402129 ;time() 004012A3 |. 83C4 04 add esp, 4 004012A6 |. 8D8D F8FEFFFF lea ecx, dword ptr [ebp-108] 004012AC |. 51 push ecx 004012AD |. E8 170D0000 call 00401FC9 ;localtime() 004012B2 |. 83C4 04 add esp, 4 004012B5 |. 8985 F4FEFFFF mov dword ptr [ebp-10C], eax 004012BB |. 8B95 F4FEFFFF mov edx, dword ptr [ebp-10C] 004012C1 |. 8B42 14 mov eax, dword ptr [edx+14] 004012C4 |. 05 6C070000 add eax, 76C 004012C9 |. A3 38E64000 mov dword ptr [40E638], eax 004012CE |. 8B8D F4FEFFFF mov ecx, dword ptr [ebp-10C] 004012D4 |. 8B51 10 mov edx, dword ptr [ecx+10] 004012D7 |. 83C2 01 add edx, 1 004012DA |. 8915 3CE64000 mov dword ptr [40E63C], edx 004012E0 |. 8B85 F4FEFFFF mov eax, dword ptr [ebp-10C] 004012E6 |. 8B48 0C mov ecx, dword ptr [eax+C] 004012E9 |. 890D 40E64000 mov dword ptr [40E640], ecx 004012EF |. C685 FCFEFFFF>mov byte ptr [ebp-104], 0 004012F6 |. B9 40000000 mov ecx, 40 004012FB |. 33C0 xor eax, eax 004012FD |. 8DBD FDFEFFFF lea edi, dword ptr [ebp-103] 00401303 |. F3:AB rep stos dword ptr es:[edi] 00401305 |. 66:AB stos word ptr es:[edi] 00401307 |. AA stos byte ptr es:[edi] 00401308 |. 68 60E64000 push 0040E660 ; /<%s> = "" 0040130D |. 8B15 40E64000 mov edx, dword ptr [40E640] ; | 00401313 |. 52 push edx ; |<%02d> => 0 00401314 |. A1 3CE64000 mov eax, dword ptr [40E63C] ; | 00401319 |. 50 push eax ; |<%02d> => 0 0040131A |. 8B0D 38E64000 mov ecx, dword ptr [40E638] ; | 00401320 |. 51 push ecx ; |<%02d> => 0 00401321 |. 68 E8B04000 push 0040B0E8 ; |Format = "Log/%02d%02d%02d_% s.log" 00401326 |. 8D95 FCFEFFFF lea edx, dword ptr [ebp-104] ; | 0040132C |. 52 push edx ; |s 0040132D |. FF15 28A14000 call dword ptr [<&USER32.wsprintfA>] ; /wsprintfA 00401333 |. 83C4 18 add esp, 18 00401336 |. 833D A0E64000>cmp dword ptr [40E6A0], 0 0040133D |. 74 18 je short 00401357 0040133F |. A1 A0E64000 mov eax, dword ptr [40E6A0] 00401344 |. 50 push eax 00401345 |. E8 290C0000 call 00401F73 ;fclose() 0040134A |. 83C4 04 add esp, 4 0040134D |. C705 A0E64000>mov dword ptr [40E6A0], 0 00401357 |> 68 00B14000 push 0040B100 ; ASCII "a+t" 0040135C |. 8D8D FCFEFFFF lea ecx, dword ptr [ebp-104] 00401362 |. 51 push ecx 00401363 |. E8 F80B0000 call 00401F60 ;fopen() 00401368 |. 83C4 08 add esp, 8 0040136B |. A3 A0E64000 mov dword ptr [40E6A0], eax 00401370 |. 833D A0E64000>cmp dword ptr [40E6A0], 0 00401377 |. 75 0E jnz short 00401387 00401379 |. 68 04B14000 push 0040B104 ; ASCII "Log create file error!" 0040137E |. FF15 ACE74000 call XXXXXXXX ;这里就不用逆了,这段代码是从我逆的代码中截下来的。 00401384 |. 83C4 04 add esp, 4 00401387 |> 8D95 FCFEFFFF lea edx, dword ptr [ebp-104] 0040138D |. 52 push edx 0040138E |. 68 A4E64000 push 0040E6A4 00401393 |. E8 68090000 call 00401D00 ;strcpy() 00401398 |. 83C4 08 add esp, 8 0040139B |. 5F pop edi 0040139C |. 8BE5 mov esp, ebp 0040139E |. 5D pop ebp 0040139F /. C3 retn //---------------------------------------------------------------- 我也把我的逆的结果发出来,大家看看,实际这个需要耐心的练习的,实际有几个CALL大家没必要逆,我这里 就不贴出来了,实际有很多C函数是被解释成汇编,一块编译进程序的,我会在以后的内容中来介绍如何处理。 我已经把函数给贴出来了,我想大家逆的时候就不郁闷了吧~,逆这段代码,我们的方法有很多,我这里就贴两种 我最常用的方法: 1、汇编的逆法 //----------------------------------------------------------------- int year =0; int month=0; int day =0; DWORD file=NULL; char *type="a+t"; char *str="test"; char *format="Log//%02d%02d%02d_%s.log"; TCHAR buf[MAX_PATH]={0}; //------------------------------------------------------------------ void _callunk() { _asm{ push ebp mov ebp, esp sub esp, 0x10C push edi lea eax, dword ptr [ebp-0x108] push eax call time add esp, 4 lea ecx, dword ptr [ebp-0x108] push ecx call localtime add esp, 4 mov dword ptr [ebp-0x10C], eax mov edx, dword ptr [ebp-0x10C] mov eax, dword ptr [edx+0x14] add eax, 0x76C mov year, eax mov ecx, dword ptr [ebp-0x10C] mov edx, dword ptr [ecx+0x10] add edx, 1 mov month, edx mov eax, dword ptr [ebp-0x10C] mov ecx, dword ptr [eax+0x0C] mov day, ecx mov byte ptr [ebp-0x104], 0 mov ecx, 0x40 xor eax, eax lea edi, dword ptr [ebp-0x103] rep stos dword ptr es:[edi] stos word ptr es:[edi] stos byte ptr es:[edi] push str mov edx, day push edx mov eax, month push eax mov ecx, year push ecx push format lea edx, dword ptr [ebp-0x104] push edx call wsprintfA add esp, 0x18 cmp file, 0 je L050 mov eax, file push eax call fclose add esp, 4 mov file, 0 L050: push type lea ecx, dword ptr [ebp-0x104] push ecx call fopen add esp, 8 mov file, eax cmp file, 0 jnz L061 ;push 0040B104 ;call XXXXXXXX ;add esp, 4 L061: lea edx, dword ptr [ebp-104] push edx push buf call strcpy add esp, 8 pop edi mov esp, ebp pop ebp retn } } //--------------------------------------------------------------- 2、直接逆成C语句 //--------------------------------------------------------------- void LogDataSet() { time_t mtm; time(&mtm); tm *ptm=::localtime(&mtm); //按逆的原则来说,应该是全局变量。 int LogMYear=ptm->tm_year+1900; int LogMonth=ptm->tm_mon+1; int LogMDay =ptm->tm_mday; TCHAR str[MAX_PATH]={0}; wsprintf(str,"Log//%02d%02d%02d_% s.log",_logdata.LogMYear,_logdata.LogMonth,_logdata.LogMDay,szServerName); if(logfp!=NULL){fclose(logfp); logfp=NULL;} logfp=fopen(str,"a+t"); if(logfp==NULL) { //这里是那个CALL //LogAdd("Log create file error!"); } strcpy(m_szLogFileName,str); } //--------------------------------------------------------------- 以上只是参考性的代码,我没拿编译器试,直接按汇编把它写了出来,大家有兴趣的可以试的。今天说到这里 大家觉得怎么样呢~~~,逆向这个东西,很多的。。一时半时,还真难给大家很明确的说明,希望高手多指点。 -by easystudy
相关推荐
关于常量传播(如何修改const常量的值)
关于常量折叠 今天在回顾C++的const_cast的时候无意写了这样一段代码: #include using namespace std; int main(){ const int i=100; int *p=const_cast(&i); (*p)++; cout<<p<<" "<<&i<<endl; cout<<*p<<" "<<i<<endl; } 运行结果如下: 0x22f
CTF Reverse 逆向技术全攻略
例如,检测玩家的操作是否符合正常游戏逻辑(如射击游戏中,检测射击频率是否异常高)、检测内存中数据的变化是否异常(如玩家的金币数量是否突然大量增加而没有经过正常的游戏流程)、检测网络通信是否存在异常(如是否有非法的数据包发送)等。在 unity 游戏中,使用 Mono 打包的代码相对更容易逆向分析。对于 IL2CPP 打包的 unity 游戏,需使用更高级的逆向分析方法,如分析生成的 C++代码(可能需要对 C++逆向有一定了解),或使用针对 IL2CPP 的工具和技巧(目前相关工具正在不断发展和完善)。
《C++反汇编与逆向分析技术揭秘》笔记-第7章变量在内存中的位置和访问方式
C++反汇编揭秘
数据逆向(二)——区分常量、变量、指针
做数据分析是这是最先应该区分数据是常量、变量,还是指针。 作为二进制数据本身不会标记自己是什么,但是编译器将全局变量、静态变量和常量统一储存在一起,因为它们的实现方式是一样的,只是全局变量
【Go】Go语言基本语法--注释、变量、常量
在Go语言中,常量(Constants)是固定不变的值,它们在编译时被确定,并且在程序的整个生命周期内都不会改变。 常量可以是字符、字符串、布尔值或数值(整数、浮点数等)。常量用于提高代码的可读性和可维护性,特别是在定义那些不应该被改变的值时(如配置参数、物理常量等)。
exe反编译工具:从二进制到VC源代码的桥梁
反编译是逆向工程的一个分支,它涉及将编译后的代码转换回可读形式的过程。随着技术的发展,各种反编译工具应运而生,它们帮助工程师们理解程序的内部结构和逻辑,支持安全分析、漏洞修复、教育目的等多个方面。
逆向分析学习入门教程
转在于 逆向工厂(一):从hello world开始前沿从本篇起,逆向工厂带大家从程序起源讲起,领略计算机程序逆向技术,了解程序的运行机制,逆向通用技术手段和软件保护技术,更加深入地去探索逆向的魅力。一、程序如何诞生?1951年4月开始在英国牛津郡哈维尔原子能研究基地正式投入使用的英国数字计算机“哈维尔·德卡特伦”,是当时世界上仅有的十几台电脑之一。图中两人手持的“纸带”即是早期的程序,纸带通过是否
从零开始:手把手教你检查并更新英伟达GPU驱动和CUDA版本(Windows/Linux双平台)
本文详细指导如何在Windows和Linux系统上检查并更新英伟达GPU驱动和CUDA版本,解决版本不匹配导致的常见问题。涵盖驱动更新、CUDA Toolkit安装、版本冲突排解及性能优化技巧,帮助开发者高效管理GPU计算环境。
170519 逆向-局部变量
1625-5 王子昂 总结《2017年5月19日》 【连续第230天总结】 A. 加密与解密 数据结构 B. 数据结构是计算机存储、组织数据的方式。逆向分析时,确定了数据结构后,算法就容易得到了。不过有些时候也会反过来,根据特定算法来判断数据结构。 局部变量: 局部变量的生命周期只在函数内部。 从汇编角度看,就是在堆栈中进行分配空间,而函数执行完毕后释放这些堆栈。 程序用"sub
android10 部分机型(华为)无法正常更新安装app
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=file://storage/emulated/0/文件夹名/***.apk typ=application/vnd.android.package-archive }
SpringBoot 中 @RequestMapping 及衍生注解的全面解析与实践
本文全面解析Spring Boot中@RequestMapping及其衍生注解的使用,涵盖核心功能、HTTP方法特定注解(@GetMapping/@PostMapping等)、属性详解(路径/参数/头信息等)以及路径变量处理。文章详细介绍了注解的组合使用、继承特性、版本控制策略等高级应用,并针对405/404等常见错误提供解决方案。通过学习这些注解的规范用法,开发者能够构建符合RESTful风格的API接口,提升代码可读性和可维护性。建议优先使用HTTP方法特定注解,合理规划URL结构,并注意避免路径冲突。
C++ 源码常量加密,防逆向破解小技巧
写在前面 做为个一个c++的搬砖猿,我很早之前就有一个想法。企图在c++代码编译时能够部分干预C++的编译过程,比如类似宏一样的行为,或者模板类的行为。在编译时才存在的一些代码或信息。而c++14 则提供了这样的特性。 实际效果 代码如下: int main() { printf("%s\r\n", ET("1234567890")); printf("%s\r\n", ("9876543210")); system("pause"); } ...
SAP 接口测试操作-业务顾问
业务顾问测试接口操作
C逆向-常量是什么
常量是在程序运行之前就被静态地存储在内存中的。这些常量在程序启动时被初始化,然后一直存在于程序的整个生命周期内,它们的值是固定的且无法被修改。因为全局const常量存储在程序的只读内存区域,所以想修改全局const常量就需要先修改该物理页的属性,修改成可读可写。常量必须在声明时进行初始化,且其值在后续程序执行期间不可改变。
【LE Audio】CAP精讲[1]: 从理论到实操,CAP 协同流程入门全攻略
LEAudio生态中的CommonAudioProfile(CAP)是一个关键协同框架,它通过整合基础音频协议(BAP/VCP/MICP等)构建多设备协同能力。CAP定义了三大核心功能:音频流管理、设备组控制和统一交互服务,解决了传统蓝牙音频在多设备场景下的协同痛点。其规范历经v1.0到v1.0.1的优化,修正了角色定义、连接流程等关键模块,提升设备兼容性。CAP采用严格的语言约定(shall/must/should)和术语体系(ContextType/CCID/协同集),确保不同厂商设备能相互理解。
【华为OD技术面试手撕真题】3、小行星碰撞 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS)
小行星碰撞,本专栏更新每年华为OD机试的高频手撕代码题,每个题目都会使用五种语言进行解答(C & C++& Java & Python & JS),思路分析都非常详细, 实现最低的时间复杂度和高通过率,每个解题思路超过百字,内含各个编程语言的八股文面试题,欢迎大家订阅学习, 代码可以直接运行使用,全网限时最低价,持续更新
X86逆向教程9:通过关键常量破解
本章将讲解一下关于关键全局变量的一些内容,关键的全局变量对于软件的破解非常的有用,找到了关键全局变量并改写它同样可以完成完美爆破一个程序,这里我将使用CM小例子来讲解搜索关键变量的一些技巧,最后我们来实战破解一个程序练练手,从本节课开始我们将进入实战环节,不再仅仅局限于CM小程序的破解啦。 -----------------------------------------------------...
【GlobalMapper精品教程】001:GlobalMapper23+24+25 Pro-x64中文汉化版安装教程(附软件包下载)
Global Mapper 23+V24+V25中文汉化版安装教程及免费下载地址,是一款非常专业的地图绘制软件,功能非常的丰富,内置距离和面积计算,包括光栅混合、对比度调节、海拔高度查询、视线计算以及一些高级功能,通过地表数据观察分水岭、对3Dpoint数据转换为三角多边形和网格化等设置。本文讲解GlobalMapper23.1 Pro-x64安装过程。
【逆向】dnSpy——修改IL代码,如何添加局部变量
本文详细介绍了在dnSpy中修改IL代码并添加局部变量的方法。核心步骤包括:打开目标方法的IL编辑模式,在局部变量表中声明新变量(需配置类型和索引),通过stloc/ldloc等指令操作变量。文章提供了实操示例,演示如何添加int类型变量并修改IL指令,同时强调了关键注意事项,如.maxstack调整、索引冲突避免和类型匹配等。最后列出了常见问题排查方法,帮助用户完成IL代码的自定义修改。整个过程需严格遵循IL语法规则,确保变量索引和指令操作正确匹配。
Debezium系列之:深入理解 Debezium Topic的设置要求
Debezium系列之:配置 Debezium Topic
RU DOS版、EFI版32bit/64bit BIOS常用工具
DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。
逆向基础-全局和局部变量
定义位置:在函数外部声明的变量,或带static的静态变量。内存位置:放在程序的数据段(Data/BSS 段)中,地址在编译/链接后就确定(相对可预测,除非启用地址空间布局随机化 ASLR)。生命周期:程序一启动,该内存段就存在;变量在进程生命周期内一直存在,直到进程结束才释放。初始值如果编译时显式初始化(例如),则在加载时包含初始值。未显式初始化的全局变量在 BSS 段通常被初始化为 0(由运行时或 C 运行时库负责)。定义位置int x;在函数里)。内存位置:一般分配在栈(stack)上;
Statistics and Machine Learning Toolbox
Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具
安卓APP逆向(六)JAVA基础
本文介绍了Java环境搭建与基础语法。首先详细讲解了JDK18的安装步骤和环境变量配置(包括JAVA_HOME、CLASSPATH设置),并验证安装成功。接着通过HelloWorld示例演示了Java程序的编写、编译和运行过程。文章还介绍了IntelliJ IDEA编辑器的安装和汉化方法。在语法部分,重点说明:程序入口必须是main方法;文件命名规范;类与成员的修饰符(public/protected/private/static);变量常量定义;输入输出方法;以及while和do-while循环的基本用法
复分析 阿尔福斯(Ahlfors) 第三版答案 英文
答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案
Windows平台C/C++程序逆向阶段总结
研究win程序逆向的初衷是为了更好的理解计算机系统的底层实现,理解计算机硬件架构与操作系统之间的联系,实现对软件系统的原子极优化。要想把win程序逆向研究透,可能并非一朝一夕。逆向需要你有多方面的知识,大的方面有组成原理,操作系统,编译原理等。往细了说,你还需要懂C/C++的语言实现与内存模型,汇编及其内存操作模型,win系统可执行程序的PE文件格式,还有msvc的工具链等。总结来说,就是你需要“懂原理,并熟练运用工具!”另外,说明一点:2021年了,现在的应用层技术层出不穷,逆向工程技术也远不止解析PE这
Android 防止逆向
软件逆向分析的出现必然会出现防止逆向分析的操作,这里介绍五种防御方式: ①代码混淆技术 ②针对不同的逆向工具的保护技术(如IDE、JD_GUI等) ③增加逆向难度(java代码Native化) ④动态加载技术 ⑤代码验证技术 代码混淆 代码混淆也称花指令,是将计算机程序的代码转化为一种功能上的等价,但是难于阅读和理解的形式的行为,代码混淆可以用于程序编译而成的中间代码,执行代码混淆的...
记录一次逆向小程序破解加密js的方法
逆向js加密可以说是一项特别有难度的技能。小程序目前(以后就不知道)相对安卓来说是比较好逆向的,因为安卓app要上架应用市场,按国家规定必须得要加固的,所以反编译出安卓app的源码比较难,相比而言小程序源码就很容易反编译出来。 首先声明: 此次逆向Js只为学习交流使用,关键代码均打码 首先找到小程序的安装包,可以找个手机,点开小程序后,找到手机文件目录。 # 一般是这样的目录, 当然有的...
今天来了,看到很热闹,我也热闹一下,大家春节过的好不好??,实际,今天带给大家的比较麻烦,不容易
理解,比起以往的来讲都要难点了,但是,相对很容易了,我是自己一点点反复的试中学习过来的,今天发出来给喜欢
逆向的朋友,我觉得逆向比我想的要复杂,而切是件耐心的磨性子的事,强烈建议没耐心的就别折腾了。反正我是领教
了。
在看这篇时大家需要有心理准备,就是汇编与C++的关系,要对C++和汇编都要很熟悉才可以,不然,很难理解
的,还有就是IDA和OD是不可少的,最好有WinHex和UE,我们要在IDA和OD中间寻找我们的答案。所以,在学习的时候大
家可以选择一些简单的程序,最好不大的,几十KB到几KB的程序,方便逆向。现在逆向的人不多,我想想学的人不会也
不多的。只是苦于没有这类书籍,记得有本什么黑客反汇编的书,是个老外写的还不错,大家有兴趣可以找找。
我这里说的不一定都是准确的,我只是将我的测试结果发出来,高手们要指点一二哦!我是个超级菜鸟,呵呵
~~~,希望别惹大家笑话,喜欢的就学习了,不喜欢的就看个乐子吧!
注意:在逆向的程序选择时,新手最好选择基本的C代码的程序,不建议选择pascal 和basic的代码,这些代码
不容易理解,而且和汇编的关系不是很明确的。逆向的时候选择C的代码,我发现很容易和汇编联系的。但是要将汇编反
过来写成C语言那就又是麻烦了。:(! 这里不建议选择MFC类程序,只建议大家选择Win32程序,这样我们的难度就小了很
多了,还有个就是不建议选择类程序,初学的时候就最好是函数、变量、指针。等学的差不多了,再加进去类和结构等
等。
//------------------------------------------------------------
第一部分 常量、变量
//------------------------------------------------------------
在逆向的时候我们可以自己写点程序,来研究的,但是我推荐Visual C++ 6.0 ,为什么是6.0呢?因为2003以
后程序被编译以后不再像6.0那样的清晰,编译器给程序加了很多垃圾进去,不太好分析。在编译的时候使用Release,
这样代码量会小,花的工夫就相对来说少很多。
我们把下面的代码编译进程序,看起来很简单的。但是结果是不一样的,所有教C语言的老师都说下面的代码结
果是一样的,但是,我发现在汇编里就不一定的哦!!很奇怪吧,大家可以自己多试试,我这里所说的都是常规状态下
的。
第一、局部变量:
//-------------------------------------------
int intbuf1=1,intbuf2=2;
int intbuf3=3;
int intbuf4=4;
//-------------------------------------------
OD反汇编以后的结果和下面的差不多的,有朋友会问了,为什么我的就没有下面的代码,只有一个retn 好像什么都没做
哦,在你的变量没做任何事时,只对其进行初试化,那么编译器在Release模式下,是不被解释的。我们在设置的C/C++
选项中,将Maximize Speed改为Default,这个时候我们就能看到了汇编代码。
//-------------------------------------------
0040135F /___FCKpd___0nbsp; 55 push ebp
00401360 |. 8BEC mov ebp, esp
00401362 |. 83EC 10 sub esp, 10
00401365 |. C745 F8 01000>mov dword ptr [ebp-8], 1
0040136C |. C745 FC 02000>mov dword ptr [ebp-4], 2
00401373 |. C745 F0 03000>mov dword ptr [ebp-10], 3
0040137A |. C745 F4 04000>mov dword ptr [ebp-C], 4
00401381 |. 8BE5 mov esp, ebp
00401383 |. 5D pop ebp
00401384 /. C3 retn
//-------------------------------------------
我们不难分析出栈顺序intbuf2-intbuf1-intbuf4-intbuf3,我不说了,大家自己思考编译器是如果解释变量的,而我们
需要注意的是dword ptr [ebp-X],我们把例子改一下:
//-------------------------------------------
BYTE intbuf1=1;
char intbuf2=2;
int intbuf3=3;
DWORD intbuf4=4;
LONG intbuf5=5;
SHORT intbuf6=6;
WORD intbuf7=7;
//-------------------------------------------
不难从下面的代码中我们可以看出,char和BYTE都对应byte ptr,SHORT和WORD都对应word ptr,LONG和DWORD都对应
dword ptr,我们就很容易分辨出源代码的类型了,简单吧,现在看到如下的汇编代码就容易理解和明白了,我想谁都可
以把它写成C代码或者其他语言的代码了。
//-------------------------------------------
0040135F /___FCKpd___0nbsp; 55 push ebp
00401360 |. 8BEC mov ebp, esp
00401362 |. 83EC 1C sub esp, 1C
00401365 |. C645 F8 01 mov byte ptr [ebp-8], 1
00401369 |. C645 FC 02 mov byte ptr [ebp-4], 2
0040136D |. C745 F0 03000>mov dword ptr [ebp-10], 3
00401374 |. C745 F4 04000>mov dword ptr [ebp-C], 4
0040137B |. C745 E8 05000>mov dword ptr [ebp-18], 5
00401382 |. 66:C745 EC 06>mov word ptr [ebp-14], 6
00401388 |. 66:C745 E4 07>mov word ptr [ebp-1C], 7
0040138E |. 8BE5 mov esp, ebp
00401390 |. 5D pop ebp
00401391 /. C3 retn
//-------------------------------------------
前面我们说了,定义地方不同在汇编中也是不同的,还有变量的类型我们先来看这样一段汇编代码,大家可以猜写出它
的C语言代码^_^
//--------------------------------------------
0040135F /___FCKpd___0nbsp; 55 push ebp
00401360 |. 8BEC mov ebp, esp
00401362 |. 83EC 0C sub esp, 0C
00401365 |. C745 F8 01000>mov dword ptr [ebp-8], 1
0040136C |. 8B45 F8 mov eax, dword ptr [ebp-8]
0040136F |. 8945 FC mov dword ptr [ebp-4], eax
00401372 |. 8B4D FC mov ecx, dword ptr [ebp-4]
00401375 |. 034D F8 add ecx, dword ptr [ebp-8]
00401378 |. 894D F8 mov dword ptr [ebp-8], ecx
0040137B |. 8B55 F8 mov edx, dword ptr [ebp-8]
0040137E |. 0355 FC add edx, dword ptr [ebp-4]
00401381 |. 8955 F4 mov dword ptr [ebp-C], edx
00401384 |. 8BE5 mov esp, ebp
00401386 |. 5D pop ebp
00401387 /. C3 retn
//--------------------------------------------
看了会不会头大了,呵呵~~~,是不是有点不同了,看看我怎么逆吧~~
//--------------------------------------------
DWORD unk1=1; //mov dword ptr [ebp-8], 1
DWORD unk2=unk1;
//mov eax, dword ptr [ebp-8]
//mov dword ptr [ebp-4], eax
//我们发现在第2句里多了个ebp-4所以我们就能确定了,有新的变量出现了,而且是DWORD类型的,EAX把变量unk1的
内//容传递到了新的变量中。
unk1=unk2+unk1;
//mov ecx, dword ptr [ebp-4]
//add ecx, dword ptr [ebp-8]
//mov dword ptr [ebp-8], ecx
//我们知道先取出unk2的值放入ecx,我们可以看到在相加后又放回了unk1;
unk3=unk1+unk2;
//mov edx, dword ptr [ebp-8]
//add edx, dword ptr [ebp-4]
//mov dword ptr [ebp-C], edx
//我想我不用解释大家一看就明白了吧~~~~
//----------------------------------------------------------
源代码如下:
int intbuf1=1;
int intbuf2=intbuf1;
intbuf1=intbuf2+intbuf1;
int intbuf3=intbuf1+intbuf2;
//----------------------------------------------------------
是不是一句都没错哦~~,我是逆了好多了,所以一看就知道了,大家在练习的时候多试试,就会发现规律的,
不是老师们说的,代码一但编译就不可能复原了,那是不准确的,可以做到几乎接近。
第二、全局变量:
代码为下面:
//----------------------------------------------------------
BYTE intbuf1=0;
char intbuf2=0;
int intbuf3=0;
DWORD intbuf4=0;
LONG intbuf5=0;
SHORT intbuf6=0;
WORD intbuf7=0;
void InitMain()
{
intbuf1=1;
intbuf2=2;
intbuf3=3;
intbuf4=4;
intbuf5=5;
intbuf6=6;
intbuf7=7;
}
//----------------------------------------------------------
汇编如下:
//----------------------------------------------------------
0040135F /___FCKpd___0nbsp; 55 push ebp
00401360 |. 8BEC mov ebp, esp
00401362 |. C605 74854000>mov byte ptr [408574], 1
00401369 |. C605 75854000>mov byte ptr [408575], 2
00401370 |. C705 78854000>mov dword ptr [408578], 3
0040137A |. C705 7C854000>mov dword ptr [40857C], 4
00401384 |. C705 80854000>mov dword ptr [408580], 5
0040138E |. 66:C705 84854>mov word ptr [408584], 6
00401397 |. 66:C705 86854>mov word ptr [408586], 7
004013A0 |. 5D pop ebp
004013A1 /. C3 retn
//------------------------------------------------------------
^_^,大家在逆向的时候会发现了把,全局变量和局部变量的区别了吧~~~,我想大家一看就明白了,局部变量是放在栈中
的,而全局变量是不放的,还有就是其它和局部变量都一样的,但是我们需要注意,指针问题,有的时候指针和变量是
一样的,不太好分辨,以后我会再给大家解释。
第三、常量
代码如下:
//------------------------------------------------------------
#define test2 2
#define test3 "123456789"
void InitMain()
{
int mm=test2;
char *pcc=test3;
}
//需要说明的是,我们用#define做的宏函数在编译的时候,是被直接编译出结果的,根据宏函数来确定是镶嵌代码还是
//直接编译结果。
//-------------------------------------------------------------
反汇编后,发现变量和指针是基本一样的,没什么明显的区别,是变量还是指针,大家多练习就是了,不是简单的说就
是什么就什么,实际指针在汇编中是以变量的形式来处理的,我们在汇编中就把指针当变量,但是在逆回到C语言中时我
们必须对其进行区分的。可以很明确的看出常量在汇编中什么怎么样处理的,我们把它逆回去不是很简单的事了吗?
//-------------------------------------------------------------
0040135F /___FCKpd___0nbsp; 55 push ebp
00401360 |. 8BEC mov ebp, esp
00401362 |. 83EC 08 sub esp, 8
00401365 |. C745 FC 02000>mov dword ptr [ebp-4], 2
0040136C |. C745 F8 30604>mov dword ptr [ebp-8], 00406030 ; ASCII "123456789"
00401373 |. 8BE5 mov esp, ebp
00401375 |. 5D pop ebp
00401376 /. C3 retn
//----------------------------------------------------------------
逆向是件不容易的事,我已经给大家很简单的示范了,想想实际没什么的,是没什么,简单,但是真的做起来就不容易
了,大家可以再多试试,就会发现,代码和汇编之间是有本质的联系的。我们可以逆出很接近原代码的代码来。
第四、实践练手
只说不练,被说成那个什么假什么把势的,好,我们就来练习一下。我想大家要是把这段代码看明白了,一定
会猜到我下次要给大家带来什么了,郁闷不??说的很简单,练起手来还蛮难^_^。
//----------------------------------------------------------------
0040128D /___FCKpd___0nbsp; 55 push ebp
0040128E |. 8BEC mov ebp, esp
00401290 |. 81EC 0C010000 sub esp, 10C
00401296 |. 57 push edi
00401297 |. 8D85 F8FEFFFF lea eax, dword ptr [ebp-108]
0040129D |. 50 push eax
0040129E |. E8 860E0000 call 00402129 ;time()
004012A3 |. 83C4 04 add esp, 4
004012A6 |. 8D8D F8FEFFFF lea ecx, dword ptr [ebp-108]
004012AC |. 51 push ecx
004012AD |. E8 170D0000 call 00401FC9 ;localtime()
004012B2 |. 83C4 04 add esp, 4
004012B5 |. 8985 F4FEFFFF mov dword ptr [ebp-10C], eax
004012BB |. 8B95 F4FEFFFF mov edx, dword ptr [ebp-10C]
004012C1 |. 8B42 14 mov eax, dword ptr [edx+14]
004012C4 |. 05 6C070000 add eax, 76C
004012C9 |. A3 38E64000 mov dword ptr [40E638], eax
004012CE |. 8B8D F4FEFFFF mov ecx, dword ptr [ebp-10C]
004012D4 |. 8B51 10 mov edx, dword ptr [ecx+10]
004012D7 |. 83C2 01 add edx, 1
004012DA |. 8915 3CE64000 mov dword ptr [40E63C], edx
004012E0 |. 8B85 F4FEFFFF mov eax, dword ptr [ebp-10C]
004012E6 |. 8B48 0C mov ecx, dword ptr [eax+C]
004012E9 |. 890D 40E64000 mov dword ptr [40E640], ecx
004012EF |. C685 FCFEFFFF>mov byte ptr [ebp-104], 0
004012F6 |. B9 40000000 mov ecx, 40
004012FB |. 33C0 xor eax, eax
004012FD |. 8DBD FDFEFFFF lea edi, dword ptr [ebp-103]
00401303 |. F3:AB rep stos dword ptr es:[edi]
00401305 |. 66:AB stos word ptr es:[edi]
00401307 |. AA stos byte ptr es:[edi]
00401308 |. 68 60E64000 push 0040E660 ; /<%s> = ""
0040130D |. 8B15 40E64000 mov edx, dword ptr [40E640] ; |
00401313 |. 52 push edx ; |<%02d> => 0
00401314 |. A1 3CE64000 mov eax, dword ptr [40E63C] ; |
00401319 |. 50 push eax ; |<%02d> => 0
0040131A |. 8B0D 38E64000 mov ecx, dword ptr [40E638] ; |
00401320 |. 51 push ecx ; |<%02d> => 0
00401321 |. 68 E8B04000 push 0040B0E8 ; |Format = "Log/%02d%02d%02d_%
s.log"
00401326 |. 8D95 FCFEFFFF lea edx, dword ptr [ebp-104] ; |
0040132C |. 52 push edx ; |s
0040132D |. FF15 28A14000 call dword ptr [<&USER32.wsprintfA>] ; /wsprintfA
00401333 |. 83C4 18 add esp, 18
00401336 |. 833D A0E64000>cmp dword ptr [40E6A0], 0
0040133D |. 74 18 je short 00401357
0040133F |. A1 A0E64000 mov eax, dword ptr [40E6A0]
00401344 |. 50 push eax
00401345 |. E8 290C0000 call 00401F73 ;fclose()
0040134A |. 83C4 04 add esp, 4
0040134D |. C705 A0E64000>mov dword ptr [40E6A0], 0
00401357 |> 68 00B14000 push 0040B100 ; ASCII "a+t"
0040135C |. 8D8D FCFEFFFF lea ecx, dword ptr [ebp-104]
00401362 |. 51 push ecx
00401363 |. E8 F80B0000 call 00401F60 ;fopen()
00401368 |. 83C4 08 add esp, 8
0040136B |. A3 A0E64000 mov dword ptr [40E6A0], eax
00401370 |. 833D A0E64000>cmp dword ptr [40E6A0], 0
00401377 |. 75 0E jnz short 00401387
00401379 |. 68 04B14000 push 0040B104 ; ASCII "Log create file error!"
0040137E |. FF15 ACE74000 call XXXXXXXX ;这里就不用逆了,这段代码是从我逆的代码中截下来的。
00401384 |. 83C4 04 add esp, 4
00401387 |> 8D95 FCFEFFFF lea edx, dword ptr [ebp-104]
0040138D |. 52 push edx
0040138E |. 68 A4E64000 push 0040E6A4
00401393 |. E8 68090000 call 00401D00 ;strcpy()
00401398 |. 83C4 08 add esp, 8
0040139B |. 5F pop edi
0040139C |. 8BE5 mov esp, ebp
0040139E |. 5D pop ebp
0040139F /. C3 retn
//----------------------------------------------------------------
我也把我的逆的结果发出来,大家看看,实际这个需要耐心的练习的,实际有几个CALL大家没必要逆,我这里
就不贴出来了,实际有很多C函数是被解释成汇编,一块编译进程序的,我会在以后的内容中来介绍如何处理。
我已经把函数给贴出来了,我想大家逆的时候就不郁闷了吧~,逆这段代码,我们的方法有很多,我这里就贴两种
我最常用的方法:
1、汇编的逆法
//-----------------------------------------------------------------
int year =0;
int month=0;
int day =0;
DWORD file=NULL;
char *type="a+t";
char *str="test";
char *format="Log//%02d%02d%02d_%s.log";
TCHAR buf[MAX_PATH]={0};
//------------------------------------------------------------------
void _callunk()
{
_asm{
push ebp
mov ebp, esp
sub esp, 0x10C
push edi
lea eax, dword ptr [ebp-0x108]
push eax
call time
add esp, 4
lea ecx, dword ptr [ebp-0x108]
push ecx
call localtime
add esp, 4
mov dword ptr [ebp-0x10C], eax
mov edx, dword ptr [ebp-0x10C]
mov eax, dword ptr [edx+0x14]
add eax, 0x76C
mov year, eax
mov ecx, dword ptr [ebp-0x10C]
mov edx, dword ptr [ecx+0x10]
add edx, 1
mov month, edx
mov eax, dword ptr [ebp-0x10C]
mov ecx, dword ptr [eax+0x0C]
mov day, ecx
mov byte ptr [ebp-0x104], 0
mov ecx, 0x40
xor eax, eax
lea edi, dword ptr [ebp-0x103]
rep stos dword ptr es:[edi]
stos word ptr es:[edi]
stos byte ptr es:[edi]
push str
mov edx, day
push edx
mov eax, month
push eax
mov ecx, year
push ecx
push format
lea edx, dword ptr [ebp-0x104]
push edx
call wsprintfA
add esp, 0x18
cmp file, 0
je L050
mov eax, file
push eax
call fclose
add esp, 4
mov file, 0
L050:
push type
lea ecx, dword ptr [ebp-0x104]
push ecx
call fopen
add esp, 8
mov file, eax
cmp file, 0
jnz L061
;push 0040B104
;call XXXXXXXX
;add esp, 4
L061:
lea edx, dword ptr [ebp-104]
push edx
push buf
call strcpy
add esp, 8
pop edi
mov esp, ebp
pop ebp
retn
}
}
//---------------------------------------------------------------
2、直接逆成C语句
//---------------------------------------------------------------
void LogDataSet()
{
time_t mtm;
time(&mtm);
tm *ptm=::localtime(&mtm);
//按逆的原则来说,应该是全局变量。
int LogMYear=ptm->tm_year+1900;
int LogMonth=ptm->tm_mon+1;
int LogMDay =ptm->tm_mday;
TCHAR str[MAX_PATH]={0};
wsprintf(str,"Log//%02d%02d%02d_%
s.log",_logdata.LogMYear,_logdata.LogMonth,_logdata.LogMDay,szServerName);
if(logfp!=NULL){fclose(logfp); logfp=NULL;}
logfp=fopen(str,"a+t");
if(logfp==NULL)
{
//这里是那个CALL
//LogAdd("Log create file error!");
}
strcpy(m_szLogFileName,str);
}
//---------------------------------------------------------------
以上只是参考性的代码,我没拿编译器试,直接按汇编把它写了出来,大家有兴趣的可以试的。今天说到这里
大家觉得怎么样呢~~~,逆向这个东西,很多的。。一时半时,还真难给大家很明确的说明,希望高手多指点。
-by easystudy
3137



被折叠的 条评论
为什么被折叠?



