2006年12月29日
易语言终于发布了许诺已久的新版本。这个版本更名为“易语言.飞扬”,是和原来版本完全不同的一个新的产品。
发布的帖子:
http://www.dywt.com.cn/vbs/dispbbs.asp?boardID=124&ID=100124&page=1
技术白皮书:
http://liigo.diy.myrice.com/efly/whitebook/index.html
http://liigo.diy.myrice.com/efly/whitebook/white_book.pdf
下载地址:
http://www.dywt.com.cn/edown/efly/efly.rar
2006年12月31日
由于这个版本是完全面向对象的,所以跟踪了一下类的创建和调用方式。
先写一段源代码,然后反汇编分析。
//////////////////////////////////////////////////////////////////////
类库TestClassLib1的原代码:
公开 类 TestClass1
{
公开 go()
{
控制台.输出行("Hello go!\n");
}
静态 公开 run()
{
控制台.输出行("Hello run!\n");
}
}
编译参数:
..\..\ec test2.ef -ecl_name="TestClassLib1" -out_mode=ecl
//////////////////////////////////////////////////////////////////////
测试程序源代码:
引入 TestClassLib1;
公开 类 启动类 <>
{
公开 静态 启动()
{
TestClass1 pObj1 = 创建 TestClass1;
pObj1.go();
TestClass1.run();
控制台.输出行("Hello world.\n");
返回;
}
}
编译参数:
..\..\ec test1.ef -ecl_name="程序" -starter_cls="启动类" -out_mode=runable -out="..\..\test1.exe"
//////////////////////////////////////////////////////////////////////
分析部分:
用OD加载生成的目标程序test1.exe。下面是程序入口处的代码:
004010AD 8D85 ECFAFFFF LEA EAX, [EBP-514]
004010B3 50 PUSH EAX
004010B4 E8 0B020000 CALL 004012C4
004010B9 68 1F104000 PUSH 0040101F ; ASCII "系统.NCL"
004010BE 8D85 ECFAFFFF LEA EAX, [EBP-514]
004010C4 50 PUSH EAX
004010C5 E8 EC010000 CALL <JMP.&KERNEL32.lstrcatA>
004010CA 50 PUSH EAX
004010CB E8 DA010000 CALL <JMP.&KERNEL32.LoadLibraryA>
004010D0 85C0 TEST EAX, EAX
004010D2 0F85 57010000 JNZ 0040122F
004010D8 8D85 E0F9FFFF LEA EAX, [EBP-620]
004010DE 50 PUSH EAX
004010DF 68 19000200 PUSH 20019
004010E4 6A 00 PUSH 0
004010E6 68 2F104000 PUSH 0040102F ; ASCII "Software\FlySky\NewE\Install"
004010EB 68 01000080 PUSH 80000001
004010F0 E8 FD010000 CALL <JMP.&ADVAPI32.RegOpenKeyExA>
004010F5 83F8 00 CMP EAX, 0
004010F8 75 7D JNZ SHORT 00401177
004010FA C785 DCF9FFFF 1>MOV DWORD PTR [EBP-624], 513
00401104 8D85 DCF9FFFF LEA EAX, [EBP-624]
0040110A 50 PUSH EAX
0040110B 8D85 ECFAFFFF LEA EAX, [EBP-514]
00401111 50 PUSH EAX
00401112 6A 00 PUSH 0
00401114 6A 00 PUSH 0
00401116 68 4C104000 PUSH 0040104C ; ASCII "Path"
0040111B FFB5 E0F9FFFF PUSH DWORD PTR [EBP-620]
00401121 E8 D2010000 CALL <JMP.&ADVAPI32.RegQueryValueExA>
00401126 50 PUSH EAX
00401127 FFB5 E0F9FFFF PUSH DWORD PTR [EBP-620]
0040112D E8 BA010000 CALL <JMP.&ADVAPI32.RegCloseKey>
00401132 58 POP EAX ; 0012F9A4
00401133 83F8 00 CMP EAX, 0
00401136 75 3F JNZ SHORT 00401177
00401138 8D85 ECFAFFFF LEA EAX, [EBP-514]
0040113E 50 PUSH EAX
0040113F E8 78010000 CALL <JMP.&KERNEL32.lstrlenA>
00401144 8D9D ECFAFFFF LEA EBX, [EBP-514]
0040114A 03D8 ADD EBX, EAX
0040114C 4B DEC EBX
0040114D 803B 5C CMP BYTE PTR [EBX], 5C
00401150 74 06 JE SHORT 00401158
00401152 66:C743 01 5C00 MOV WORD PTR [EBX+1], 5C
00401158 68 1F104000 PUSH 0040101F ; ASCII "系统.NCL"
0040115D 8D85 ECFAFFFF LEA EAX, [EBP-514]
00401163 50 PUSH EAX
00401164 E8 4D010000 CALL <JMP.&KERNEL32.lstrcatA>
00401169 50 PUSH EAX
0040116A E8 3B010000 CALL <JMP.&KERNEL32.LoadLibraryA>
0040116F 85C0 TEST EAX, EAX
00401171 0F85 B8000000 JNZ 0040122F
00401177 68 14050000 PUSH 514
0040117C 8D85 ECFAFFFF LEA EAX, [EBP-514]
00401182 50 PUSH EAX
00401183 68 51104000 PUSH 00401051 ; ASCII "ECLS_PATHS"
00401188 E8 11010000 CALL <JMP.&KERNEL32.GetEnvironmentVar>
0040118D 83F8 00 CMP EAX, 0
00401190 0F84 8D000000 JE 00401223
00401196 3D 14050000 CMP EAX, 514
0040119B 0F83 82000000 JNB 00401223
004011A1 C785 D8F9FFFF 0>MOV DWORD PTR [EBP-628], 0
004011AB 8D9D ECFAFFFF LEA EBX, [EBP-514]
004011B1 83BD D8F9FFFF 0>CMP DWORD PTR [EBP-628], 0
004011B8 75 69 JNZ SHORT 00401223
004011BA 8BD3 MOV EDX, EBX
004011BC 8A03 MOV AL, [EBX]
004011BE 3C 3B CMP AL, 3B
004011C0 74 17 JE SHORT 004011D9
004011C2 3C 2C CMP AL, 2C
004011C4 74 13 JE SHORT 004011D9
004011C6 3C 00 CMP AL, 0
004011C8 75 0C JNZ SHORT 004011D6
004011CA C785 D8F9FFFF 0>MOV DWORD PTR [EBP-628], 1
004011D4 EB 03 JMP SHORT 004011D9
004011D6 43 INC EBX
004011D7 ^ EB E3 JMP SHORT 004011BC
004011D9 8BCB MOV ECX, EBX
004011DB 2BCA SUB ECX, EDX ; ntdll.KiFastSystemCallRet
004011DD 74 41 JE SHORT 00401220
004011DF 53 PUSH EBX
004011E0 51 PUSH ECX
004011E1 51 PUSH ECX
004011E2 52 PUSH EDX ; ntdll.KiFastSystemCallRet
004011E3 8D85 E8F9FFFF LEA EAX, [EBP-618]
004011E9 50 PUSH EAX
004011EA E8 C1000000 CALL <JMP.&KERNEL32.RtlMoveMemory>
004011EF 59 POP ECX ; 0012F9A4
004011F0 8D9D E8F9FFFF LEA EBX, [EBP-618]
004011F6 03D9 ADD EBX, ECX
004011F8 4B DEC EBX
004011F9 803B 5C CMP BYTE PTR [EBX], 5C
004011FC 74 01 JE SHORT 004011FF
004011FE 43 INC EBX
004011FF 66:C703 5C00 MOV WORD PTR [EBX], 5C
00401204 68 1F104000 PUSH 0040101F ; ASCII "系统.NCL"
00401209 8D85 E8F9FFFF LEA EAX, [EBP-618]
0040120F 50 PUSH EAX
00401210 E8 A1000000 CALL <JMP.&KERNEL32.lstrcatA>
00401215 50 PUSH EAX
00401216 E8 8F000000 CALL <JMP.&KERNEL32.LoadLibraryA>
0040121B 5B POP EBX ; 0012F9A4
0040121C 85C0 TEST EAX, EAX
0040121E 75 0F JNZ SHORT 0040122F
00401220 43 INC EBX
00401221 ^ EB 8E JMP SHORT 004011B1
00401223 68 1F104000 PUSH 0040101F ; ASCII "系统.NCL"
00401228 E8 7D000000 CALL <JMP.&KERNEL32.LoadLibraryA>
0040122D 74 43 JE SHORT 00401272
0040122F 8985 E4F9FFFF MOV [EBP-61C], EAX
00401235 68 28104000 PUSH 00401028 ; ASCII "RunECL"
0040123A 50 PUSH EAX
0040123B E8 64000000 CALL <JMP.&KERNEL32.GetProcAddress>
00401240 85C0 TEST EAX, EAX
00401242 74 23 JE SHORT 00401267
00401244 8B25 00304000 MOV ESP, [403000]
0040124A 6A 00 PUSH 0
0040124C 6A 00 PUSH 0
0040124E E8 00000000 CALL 00401253
00401253 810424 AD2D0000 ADD DWORD PTR [ESP], 2DAD
0040125A FC CLD
0040125B FFD0 CALL EAX
0040125D 83C4 0C ADD ESP, 0C
00401260 6A 00 PUSH 0
00401262 E8 2B000000 CALL <JMP.&KERNEL32.ExitProcess>
00401267 FFB5 E4F9FFFF PUSH DWORD PTR [EBP-61C] ; ADVAPI32.77DA9BB8
0040126D E8 26000000 CALL <JMP.&KERNEL32.FreeLibrary>
00401272 6A 10 PUSH 10
00401274 68 A7104000 PUSH 004010A7 ; ASCII "Error"
00401279 68 5C104000 PUSH 0040105C ; ASCII "Not found the kernel class library or the kernel class library is invalid!"
0040127E 6A 00 PUSH 0
00401280 E8 07000000 CALL <JMP.&USER32.MessageBoxA>
00401285 B8 FFFFFFFF MOV EAX, -1
0040128A C9 LEAVE
0040128B C3 RETN
首先根据环境变量得到系统库的地址,目前是"系统.NCL"。然后得到"RunECL"函数的地址,用"RunECL(ecode RVA)"的方式调用。RunECL函数应该就是这个版本易语言的Loader,负责加载ecode RVA处的易格式。
等待Loader加载完成后,会返回到真正代码的领空。使用OD在00404108处下硬件断点可以在入口处断下来。不要下int3断点,好像Loader会对ecode的内存映像做类似于CRC的监测,所以如果下int3断点的话会直接从Loader中退出。
下面是ecode真正入口处的代码:
00404108 55 PUSH EBP
00404109 8BEC MOV EBP, ESP
0040410B 83EC 08 SUB ESP, 8
0040410E C745 FC 0000000>MOV DWORD PTR [EBP-4], 0
00404115 68 12424000 PUSH 00404212 ; UNICODE "TestClassLib1.TestClass1"
0040411A E8 51A0C00F CALL 1000E170
0040411F 83C4 04 ADD ESP, 4
00404122 8945 F8 MOV [EBP-8], EAX
00404125 8D4D FC LEA ECX, [EBP-4]
00404128 51 PUSH ECX
00404129 FF75 F8 PUSH DWORD PTR [EBP-8]
0040412C E8 5FB1C00F CALL 1000F290
00404131 83C4 08 ADD ESP, 8
00404134 8B45 FC MOV EAX, [EBP-4]
00404137 E8 6499C10F CALL 1001DAA0
0040413C 50 PUSH EAX
0040413D 8B40 04 MOV EAX, [EAX+4]
00404140 8B40 10 MOV EAX, [EAX+10]
00404143 FF50 00 CALL [EAX]
00404146 83C4 04 ADD ESP, 4
00404149 6A 01 PUSH 1
0040414B 68 12424000 PUSH 00404212 ; UNICODE "TestClassLib1.TestClass1"
00404150 E8 4BAEC00F CALL 1000EFA0
00404155 83C4 08 ADD ESP, 8
00404158 FFD0 CALL EAX
0040415A 68 44424000 PUSH 00404244
0040415F 6A 07 PUSH 7
00404161 68 64424000 PUSH 00404264 ; ASCII "?唼."
00404166 E8 35AEC00F CALL 1000EFA0
0040416B 83C4 08 ADD ESP, 8
0040416E FFD0 CALL EAX
00404170 83C4 04 ADD ESP, 4
00404173 FF75 FC PUSH DWORD PTR [EBP-4]
00404176 E8 45B1C00F CALL 1000F2C0
0040417B 83C4 04 ADD ESP, 4
0040417E 8BE5 MOV ESP, EBP
00404180 5D POP EBP ; 0038A968
00404181 C3 RETN
根据上面的源代码很容易分析出调用方法。由于是完全面向对象的编程,所以所有的调用都是基于Class的。调用分为Class static function的调用和Class virtual interface的调用。
如下代码:
00404149 6A 01 PUSH 1
0040414B 68 12424000 PUSH 00404212 ; UNICODE "TestClassLib1.TestClass1"
00404150 E8 4BAEC00F CALL 1000EFA0
00404155 83C4 08 ADD ESP, 8
00404158 FFD0 CALL EAX
是“TestClass1.run();”语句反汇编代码。
实际上做的类似如下的操作:
pAddr = GetVirtualAddress(UNICODE_Class_Name, Function_Index);
pAddr();
使用的是C方式的压栈方式。
由于这个版本的易语言类库支持类似于Java的反射功能,即RTTI。很明显可以看出编译的代码中已经完全开始使用这种技术来代替以前版本中的Function Table + Index的调用方式了。首先根据“组件名称.函数名称”来得到真正静态函数的地址,然后通过C方式压栈调用这个函数。
如下代码:
0040415A 68 44424000 PUSH 00404244
0040415F 6A 07 PUSH 7
00404161 68 64424000 PUSH 00404264 ; ASCII "?唼."
00404166 E8 35AEC00F CALL 1000EFA0
0040416B 83C4 08 ADD ESP, 8
0040416E FFD0 CALL EAX
00404170 83C4 04 ADD ESP, 4
也是类似的调用模式。
是代码“控制台.输出行("Hello world.\n");”的反汇编结果。地址00404264处是unicode的“系统.控制台”,然后根据静态函数序号“7”来得到“输出行”函数的指针。回栈后“PUSH 00404244”就变成了“输出行”函数的参数。
下面代码:
0040410E C745 FC 0000000>MOV DWORD PTR [EBP-4], 0
00404115 68 12424000 PUSH 00404212 ; UNICODE "TestClassLib1.TestClass1"
0040411A E8 51A0C00F CALL 1000E170 ;创建类TestClass1
0040411F 83C4 04 ADD ESP, 4
00404122 8945 F8 MOV [EBP-8], EAX ;得到this指针
00404125 8D4D FC LEA ECX, [EBP-4]
00404128 51 PUSH ECX
00404129 FF75 F8 PUSH DWORD PTR [EBP-8]
0040412C E8 5FB1C00F CALL 1000F290
00404131 83C4 08 ADD ESP, 8
00404134 8B45 FC MOV EAX, [EBP-4]
00404137 E8 6499C10F CALL 1001DAA0
0040413C 50 PUSH EAX ;压入this指针作为第一个隐含参数
0040413D 8B40 04 MOV EAX, [EAX+4] ;根据this指针取到虚表
00404140 8B40 10 MOV EAX, [EAX+10] ;根据虚表取到成员go的地址
00404143 FF50 00 CALL [EAX] ;go
00404146 83C4 04 ADD ESP, 4
是类成员函数的调用。即:
TestClass1 pObj1 = 创建 TestClass1;
pObj1.go();
首先还是使用UNICODE的类名称来进行类的创建,然后在0040413C出压入this指针,0040413D处取出虚表地址,00404140处从虚表里得到要道用的函数“go”的地址。然后“CALL [EAX]”直接调用。
具体的分析参见上面的注释。
放假前闲来无事随手写写,不当之处各位大虾请勿见怪。剩下的时间可以搞Zune去了^_^。论坛里如果有朋友对Zune感兴趣,可以联系我;)
2007年01月04日
今天分析了一部分Loader的行为,包括CheckSum(记得上一篇说过的Loader中有类似CRC之类的东西么^_^)和重定位修正,而且代码的加载模式也略有眉目了。
先从内存中dump一段数据出来,ecode节的:
00404000 43 4E 44 4C 01 00 00 00 00 00 00 00 08 11 06 20 乃?...??
00404010 02 00 00 00 70 65 6E 63 00 00 00 00 00 00 00 00 .数据....
00404020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
00404030 00 00 00 00 82 01 00 00 00 A2 CA 44 01 00 00 00 ..?.??.
00404040 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .......
00404050 00 00 00 00 01 00 00 00 00 00 00 00 07 00 00 00 ......
00404060 0D 00 0A 00 00 00 00 00 00 00 F0 3F 01 00 00 00 .....?.
00404070 00 00 00 00 00 00 00 00 16 00 00 00 00 00 00 00 .......
00404080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
00404090 01 00 00 00 60 00 00 00 00 00 00 00 64 00 00 00 .`...d.
004040A0 01 00 00 10 16 00 00 00 00 00 00 00 00 00 00 00 ?.....
004040B0 00 00 00 00 1A FC 01 00 00 00 00 00 01 00 00 00 ..?...
004040C0 00 00 00 00 00 00 F0 3F FF FF FF FF 00 00 00 00 ...?....
004040D0 01 00 00 00 84 00 00 00 62 E4 01 00 00 00 00 00 .?.?..
004040E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
004040F0 01 00 00 00 46 01 00 00 00 00 00 00 00 00 00 00 .?.....
00404100 00 00 00 00 00 00 00 00 55 8B EC 83 EC 08 C7 45 ....紫???
00404110 FC 00 00 00 00 68 24 00 00 00 E8 04 00 00 00 83 ü.栀$.?.?
00404120 C4 04 89 45 F8 8D 4D FC 51 FF 75 F8 E8 78 00 00 ??跸?q?磨.
00404130 00 83 C4 08 8B 45 FC E8 C4 00 00 00 50 8B 40 04 ?????.资р
00404140 8B 40 10 FF 50 00 83 C4 04 6A 01 68 24 00 00 00 ?0P???$.
00404150 E8 58 00 00 00 83 C4 08 FF D0 68 56 00 00 00 6A ?.???器.?
00404160 07 68 76 00 00 00 E8 58 00 00 00 83 C4 08 FF D0 标v.?.???
00404170 83 C4 04 FF 75 FC E8 80 00 00 00 83 C4 04 8B E5 ?$?胨.??E
00404180 5D C3 02 00 00 10 90 00 00 00 00 00 00 00 00 00 ???....
00404190 00 00 00 00 00 00 D7 A6 00 00 00 00 00 00 00 00 ...?....
004041A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
004041B0 00 00 CC 00 00 00 00 00 00 00 00 00 00 00 08 11 .?.....?
004041C0 06 20 01 00 00 00 38 5E CF 91 00 00 00 00 00 00 ?.常量...
004041D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
004041E0 00 00 00 00 00 00 96 00 00 00 59 44 4A 2F 96 00 ...?.???
004041F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B 7A .......程
00404200 8F 5E 00 00 0B 7A 8F 5E 2E 00 2F 54 A8 52 7B 7C 序.程序.启动类
00404210 00 00 54 00 65 00 73 00 74 00 43 00 6C 00 61 00 .TestCla
00404220 73 00 73 00 4C 00 69 00 62 00 31 00 2E 00 54 00 ssLib1.T
00404230 65 00 73 00 74 00 43 00 6C 00 61 00 73 00 73 00 estClass
00404240 31 00 00 00 00 00 00 00 48 00 65 00 6C 00 6C 00 1...Hell
00404250 6F 00 20 00 77 00 6F 00 72 00 6C 00 64 00 2E 00 o world.
00404260 0A 00 00 00 FB 7C DF 7E 2E 00 A7 63 36 52 F0 53 ..系统.控制台
00404270 00 00 FB 7C DF 7E 2E 00 F9 5B 61 8C 00 00 2F 54 .系统.对象.启
00404280 A8 52 00 00 08 11 06 20 03 00 00 00 CD 91 9A 5B 动.??.重定
00404290 4D 4F 70 65 6E 63 00 00 00 00 00 00 00 00 00 00 位数据.....
004042A0 00 00 00 00 00 00 00 00 00 00 00 00 4C 00 00 00 ......L.
004042B0 E6 0F 00 80 04 00 00 80 3C 00 00 80 58 00 00 60 ?耀耀<耀X怀
004042C0 60 00 00 60 DA 00 00 80 DF 00 00 40 F1 00 00 40 `怀?耀????
004042D0 FC 00 00 40 10 01 00 80 15 01 00 40 1F 01 00 80 ü??耀???耀
004042E0 26 01 00 80 2B 01 00 40 3B 01 00 40 68 00 00 80 ?耀ī???h耀
004042F0 98 00 00 80 4A 01 00 80 76 01 00 60 B8 00 00 60 ?耀?耀?怀?怀
00404300 08 11 06 20 00 00 00 00 D3 7E 5F 67 00 00 00 00 ??..结束..
wchar g_awAllSectionName[][16] = {"数据", "常量", "重定位数据", "结束"};
#define E_Section_Head_Size 0x30
#define E_CompileSign 0x20061108
int g_ECode_Size = PEThisSectionSize;
struct E_Code
{
char m_au8ECodeSign[4] = {'C', 'N', 'D', 'L'};
if(*(DWORD *)m_au8ECodeSign != 0x4c444e43)
{
break;
}
DWORD m_u32Unknow1;
if(m_u32Unknow1 > 1)
{
break;
}
DWORD m_u32Unknow2;
g_ECode_Size -= 0x0c;
if(g_ECode_Size == -1)
{
break;
}
while(true)
{
if(g_ECode_Size < E_Section_Head_Size)
{
break;
}
struct E_Section
{
g_ECode_Size -= E_Section_Head_Size;
if(g_ECode_Size == -1)
{
break;
}
//E_Section Head
DWORD m_u32CompileSign;
DWORD m_u32SectionType;
wchar m_awSectionName[16];
DWORD m_u32SectionSize;
DWORD m_u32CheckSum;
if(m_u32CompileSign != E_CompileSign)
{
break;
}
if(m_u32SectionSize == 0xffffffff)
{
break;
}
ThisCheckSum = 0;
for(i = 0; i < (m_u32SectionSize / 4); i++)
{
ThisCheckSum += (DWORD)(E_Section + E_Section_Head_Size)[i];
}
if(ThisCheckSum != m_u32CheckSum)
{
break;
}
//E_Section Body
if(*(DWORD *)((BYTE *)m_awSectionName + 0x24) == 0x0001)
{
break;
}
if(m_u32SectionType > 4)
{
continue;
}
if(!wstrcmp(awSectionName, "结束") || (m_u32SectionType == 0x00))
{
break;
}
else if(!wstrcmp(awSectionName, "数据") || (m_u32SectionType == 0x02))
{
/*
Data
looks like RTTI
DOWRD PTR 00404040 = ecl_name;
DOWRD PTR 00404078 = starter_cls;
DOWRD PTR 00404090 = Class Count;
*/
/*
Code
*/
struct
{
DWORD m_u32unknow1;
DWORD m_u32unknow2;
DWORD m_u32unknow3;
DWORD m_u32unknow4;
DWORD m_u32unknow5;
DWORD m_u32unknow6;
DWORD m_u32unknow7;
DWORD m_u32unknow8;
DWORD m_u32unknow9;
DWORD m_u32unknow10;
DWORD m_u32unknow11;
DWORD m_u32unknow12;
DWORD m_u32unknow13 = Main Code Offset;
DWORD m_u32unknow14;
DWORD m_u32unknow15;
}
}
else if(!wstrcmp(awSectionName, "常量") || (m_u32SectionType == 0x01))
{
}
else if(!wstrcmp(awSectionName, "重定位数据") || (m_u32SectionType == 0x03))
{
struct E_Relocation
{
unsigned m_btType : 3;
unsigned m_dwOffset: 29;
}
for(i = 0; i < (m_u32SectionSize / 4); i++)
{
E_Relocation ThisRel = (E_Relocation)((DWORD)(E_Section + E_Section_Head_Size)[i]);
//ThisRel.m_btType--;
if((ThisRel.m_btType - 1) > 3)
{
break;
}
if(ThisRel.m_btType == 0x02) // 0x40
{
*(DWORD *)(E_Section["数据"] + E_Section_Head_Size + ThisRel.m_dwOffset) += #SystemFuncAddr;
}
else if(ThisRel.m_btType == 0x03) // 0x60
{
*(DWORD *)(E_Section["数据"] + E_Section_Head_Size + ThisRel.m_dwOffset) += (E_Section["数据"] + E_Section_Head_Size);
}
else if(ThisRel.m_btType == 0x04) // 0x80
{
*(DWORD *)(E_Section["数据"] + E_Section_Head_Size + ThisRel.m_dwOffset) += (E_Section["常量"] + E_Section_Head_Size);
}
}
}
}
}
}
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!