首页
社区
课程
招聘
[求助]IAT 的位置可以改变不?
发表于: 2012-8-13 17:55 5726

[求助]IAT 的位置可以改变不?

2012-8-13 17:55
5726
正常程序

0040102A  |.  6A 40                 push    40                               ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040102C  |.  68 2C204200           push    0042202C                         ; |Title = "Test"
00401031  |.  68 1C204200           push    0042201C                         ; |Text = "Hello World"
00401036  |.  6A 00                 push    0                                ; |hOwner = NULL
00401038  |.  FF15 ACA24200         call    dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA

这个就是 MessageBoxA 内存地址
0042A2AC >EA 07 D5 77 00 00 00 00 00 00 00 00 00 00 00 00  ?誻............

修改后的程序

将 输入表 中的 FirstThunk 偏移了 0x10h 的位置
载入OD         内存地址已经出来 说明改的 输入表 数据没有错误
0042A2AC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0042A2BC >EA 07 D5 77 00 00 00 00 00 00 00 00 00 00 00 00  ?誻............
0042A2CC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

// 这里的数据 依然指向 42A2AC的位置
0040102A  |.  6A 40                 push    40
0040102C  |.  68 2C204200           push    0042202C                         ;  ASCII "Test"
00401031  |.  68 1C204200           push    0042201C                         ;  ASCII "Hello World"
00401036  |.  6A 00                 push    0
00401038  |.  FF15 ACA24200         call    dword ptr [42A2AC]

IAT位置可以修改不.. 还需要操作哪些?

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费
支持
分享
最新回复 (6)
雪    币: 223
活跃值: (516)
能力值: ( LV13,RANK:520 )
在线值:
发帖
回帖
粉丝
2
iat 可以移动,

但是很复杂.

给你提供两个思路.
1. 利用反汇编引擎找出所有数据.修改.
2. 把iat清空, 利用veh一个个捕获.把所有异常的地址,纪录下来,做成一个表,就像relocation那样.
然后再修改表格中地址指向的数据, 即 "IAT"

不知道对你有没有帮助.
2012-8-13 19:05
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
可以,只要不违反原则,不占据有效数据地址的话,神马空白地方都可以
2012-8-13 19:27
0
雪    币: 7115
活跃值: (639)
能力值: (RANK:1290 )
在线值:
发帖
回帖
粉丝
4
很简单的。 遍历代码节把所有引用找出来 然后记录。 修改以后在重新自己填充一遍就OK。 貌似我OPEN SOURCE过
2012-8-14 13:43
0
雪    币: 7115
活跃值: (639)
能力值: (RANK:1290 )
在线值:
发帖
回帖
粉丝
5
貌似以前没在论坛上发过。    以下是加解密函数。 很简单遍历代码节把引用都找出来判断是否是IAT的范围内 是就抽出来记录。 解密时重新构造表填充。 再把原先的位置指定到新的位置  收功。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
/*
 * 介绍:
 *    力量解密引入表
 *
 * 参数:
 *    pMem:要保护函数的映射
 *    addrOrigImageBase:要保护函数原先的基地址
 *    pImportProtect:引入表保护结构指针
 *    bOnFile:是否是文件
 *    ofJmpTableRva:新的引入跳转表的RVA
 */
PREFERENCE_IMPORT_TABLE_ADDRESS __API__ PowerEncryptImportTable(__memory pMem, __address addrOrigImageBase, PIMPORT_PROTECT pImportProtect, __bool bOnFile, __offset ofJmpTableRva) {
    __byte bXor = 0;
    __memory pCodeStart = NULL;
    __integer iCodeSize = 0;
    __integer iProcCount = 0, iLibCount = 0, iIndex = 0;
    __address addrImageBase = 0;
    __address addrCurrOrigImageBase = 0;
    __address OrigJmpAddressTable[__MAX_JMP_ADDRESS_TABLE_COUNT__] = {0};
    __bool JmpAddressTableMakeSure[__MAX_JMP_ADDRESS_TABLE_COUNT__] = {0};//用于确认当前位置是否被占用
    JMPTABLE_TO_ADDRESS JmpTableToAddressList[__MAX_JMP_ADDRESS_TABLE_COUNT__] = {0};
    __integer iJmpAddressTableCount = 0;
    __dword *pJmpAddressTableRva = NULL;
    __address addrNowAddress = 0;
    PIMAGE_NT_HEADERS pNtHdr = NULL;
    PIMAGE_DATA_DIRECTORY pImageImportDataDirectory = NULL;
    PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = NULL;
    ud_t ud_obj = {0};
    PREFERENCE_IMPORT_TABLE_ADDRESS pReferenceImportTableAddres = NULL;
    PREFERENCE_IMPORT_TABLE_ADDRESS *pCurrReferenceImportTableAddresPoint = &pReferenceImportTableAddres;
 
    // 初始化数据
    pImageImportDataDirectory = ExistDataDirectory(pMem, IMAGE_DIRECTORY_ENTRY_IMPORT);
    if (!pImageImportDataDirectory)
        return NULL;
 
    /*
     * 获取目标映射的基地址
     * 要修复的基地址可以通过函数的参数addrOrigImageBase指定,如果addrOrigImageBase == 0xFFFFFFFF则使用
     * addrImageBase,如果addrOrigImageBase != 0xFFFFFFFF,则使用addrOrigImageBase
     */
    pNtHdr = GetNtHeader(pMem);
    addrImageBase = pImportProtect->addrImageBase;
 
    // 获取目标文件代码段的地址与长度
    if (bOnFile) {
        //addrImageBase = (__address)(pNtHdr->OptionalHeader.ImageBase);
        pImageImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(pMem + Rva2Raw(pMem, pImageImportDataDirectory->VirtualAddress));
        pCodeStart = pMem + GetEntryPointSection(pMem)->PointerToRawData;
    } else {
        //addrImageBase = (__address)pMem;
        pImageImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)__RvaToVa__(pMem, pImageImportDataDirectory->VirtualAddress);
        pCodeStart = pMem + GetEntryPointSection(pMem)->VirtualAddress;
    }
    iCodeSize = GetEntryPointSection(pMem)->Misc.VirtualSize;
    __logic_memset__(JmpAddressTableMakeSure, FALSE, __MAX_JMP_ADDRESS_TABLE_COUNT__);
 
    // 设置IMAGE_PROTECT
    bXor = (__byte)GenerateRandomNumber();//随机生成出一个KEY
    pImportProtect->bXor = bXor;
 
    // 将引入表信息存入IMPORT_PROTECT结构
    // 有些程序只适用FirstThunk
    while (pImageImportDescriptor->FirstThunk) {
        __address addrCurrAddress = 0;
        __dword dwCurrRva = 0;
        __char *svDllName = NULL;
        PIMAGE_THUNK_DATA pTdIn = NULL;
        PIMAGE_THUNK_DATA pTdOut = NULL;
        if (bOnFile)
            svDllName = (__char *)(pMem + Rva2Raw(pMem, pImageImportDescriptor->Name));
        else
            svDllName = (__char *)__RvaToVa__(pMem, pImageImportDescriptor->Name);
 
        EncryptIATCallBack(iLibCount, LIB_NAME, (__memory)svDllName, __logic_strlen__(svDllName), FALSE, 0, (__void *)pImportProtect);
 
        // 填充引入表地址
        if (bOnFile) {
            pTdIn = (PIMAGE_THUNK_DATA)(pMem + Rva2Raw(pMem, pImageImportDescriptor->OriginalFirstThunk));
            pTdOut = (PIMAGE_THUNK_DATA)(pMem + Rva2Raw(pMem, pImageImportDescriptor->FirstThunk));
            // 没有OriginalFirstThunk的情况
            if ((__memory)pTdIn == pMem)
                pTdIn = pTdOut;
        } else {
            pTdIn = (PIMAGE_THUNK_DATA)__RvaToVa__(pMem, pImageImportDescriptor->OriginalFirstThunk);
            pTdOut = (PIMAGE_THUNK_DATA)__RvaToVa__(pMem, pImageImportDescriptor->FirstThunk);
            // 没有OriginalFirstThunk的情况
            if ((__memory)pTdIn == pMem)
                pTdIn = pTdOut;
        }
         
        iProcCount = 0;
        if (addrOrigImageBase == __USE_DEF_IMAGEBASE_AS_ORIG__)
            addrCurrOrigImageBase = addrImageBase;
        else
            addrCurrOrigImageBase = addrOrigImageBase;
        addrCurrAddress = __RvaToVa__(addrCurrOrigImageBase, pImageImportDescriptor->FirstThunk);
 
        // 加密函数
        while (pTdIn->u1.Function) {
            // 随机取出一个要放入的位置
            __integer iOffsetTableIndex = RandJmpAddress(&JmpAddressTableMakeSure);
 
            // 获取新的FirstThunk
            __dword dwNewFirstThunk = (__dword)(ofJmpTableRva + iOffsetTableIndex * sizeof(__address));
            OrigJmpAddressTable[iJmpAddressTableCount] = addrCurrAddress;
            JmpTableToAddressList[iJmpAddressTableCount].addrAddress = addrCurrAddress;
            // 合成新的引入地址表偏移
            JmpTableToAddressList[iJmpAddressTableCount].dwNewRva = dwNewFirstThunk;
            iJmpAddressTableCount++;//跳入表计数
 
            // 以序号引出还是以函数名引出
            if (pTdIn->u1.Ordinal & IMAGE_ORDINAL_FLAG32) {
                __word wOrd = pTdIn->u1.Ordinal;
                EncryptIATCallBack(iIndex, PROC_NAME, (__memory)&wOrd, 2, TRUE, dwNewFirstThunk, (__void *)pImportProtect);
            } else {
                __char *szProcName = NULL;
                PIMAGE_IMPORT_BY_NAME pIbn = NULL;
                if (bOnFile)
                    pIbn = (PIMAGE_IMPORT_BY_NAME)(pMem + Rva2Raw(pMem, pTdIn->u1.AddressOfData));
                else
                    pIbn = (PIMAGE_IMPORT_BY_NAME)__RvaToVa__(pMem, pTdIn->u1.AddressOfData);
                szProcName = (__char *)(pIbn->Name);
                EncryptIATCallBack(iIndex, PROC_NAME, (__memory)szProcName, __logic_strlen__(szProcName), FALSE, dwNewFirstThunk, (__void *)pImportProtect);
            }
            // 下一个函数
            addrCurrAddress += sizeof(__address);
            iProcCount++;//函数计数增加
            iIndex++;//索引计数增加
            pTdIn++;
            pTdOut++;
        }/* end while */
         
        // 在下一个DLL之前,记录当前库所有的API数量
        pImportProtect->iApiNumberInThisLibrary[iLibCount] = iProcCount;
        // 下一个DLL
        pImageImportDescriptor++;
        iLibCount++;
    }/* end while */
 
    pJmpAddressTableRva = &(pImportProtect->dwFirstThunkList);
 
    // 验证
    if (iIndex != pImportProtect->iApiNameCrc32Count)
        return NULL;
 
    // 进行随机混淆
    ud_init(&ud_obj);
    ud_set_input_buffer(&ud_obj, pCodeStart, iCodeSize);//默认一个函数的最大长度为4096
    ud_set_mode(&ud_obj, 32);
    ud_set_syntax(&ud_obj, UD_SYN_INTEL);
    while (ud_disassemble(&ud_obj)) {
        __memory pFileSaveAddress = NULL;
        struct ud_operand *pCurrOperand = NULL;
        /*
         * 找到拥有内存访问能力的指令,如果指令访问的内存地址在表中的话,则将其改写为新的内存
         * 地址
         */
        if (ud_obj.operand[0].type != UD_NONE) {
            // 如果拥有操作数
            __integer iOperandCount = 0;
 
            ///*
            // * 这里仅处理MOV,CALL,JMP 三条指令
            // * 因为不同编译只有这三条指令会对引入表造成访问
            // */
            //if (ud_obj.mnemonic == UD_Imov) {
            //    if ((ud_obj.operand[1].type == UD_OP_MEM) && (ud_obj.operand[1].base == UD_NONE) && \
            //        (ud_obj.operand[1].index == UD_NONE) && (ud_obj.operand[1].size == 32)) {
            //            pCurrOperand = &(ud_obj.operand[1]);
            //            pFileSaveAddress = (__memory)(ud_obj.inp_buff) - sizeof(__dword);
            //    }
            //} else if ((ud_obj.mnemonic == UD_Icall) || (ud_obj.mnemonic == UD_Ijmp)) {
            //    if ((ud_obj.operand[0].type == UD_OP_MEM) && (ud_obj.operand[0].base == UD_NONE) && \
            //        (ud_obj.operand[0].index == UD_NONE) && (ud_obj.operand[0].offset) && (ud_obj.operand[0].size == 32)) {
            //            pCurrOperand = &(ud_obj.operand[0]);
            //            pFileSaveAddress = (__memory)(ud_obj.inp_buff) - sizeof(__dword);
            //    }
            //}
 
            //////////////////////////////////////////////////////////////////////////
            // 2012.2.10 修改为 所有指令只要有内存访问
            // 形如:xxx dword ptr [address]
            //      xxx dword ptr [address], reg
            //      xxx reg, dword ptr [address]
            if ((ud_obj.operand[0].type == UD_OP_MEM) && (ud_obj.operand[0].base == UD_NONE) && \
                (ud_obj.operand[0].index == UD_NONE) && (ud_obj.operand[0].offset) && (ud_obj.operand[0].size == 32)) {
                    pCurrOperand = &(ud_obj.operand[0]);
                    pFileSaveAddress = (__memory)(ud_obj.inp_buff) - sizeof(__dword);
            }
            else if ((ud_obj.operand[1].type == UD_OP_MEM) && (ud_obj.operand[1].base == UD_NONE) && \
                (ud_obj.operand[1].index == UD_NONE) && (ud_obj.operand[1].size == 32)) {
                    pCurrOperand = &(ud_obj.operand[1]);
                    pFileSaveAddress = (__memory)(ud_obj.inp_buff) - sizeof(__dword);
            }
 
            if (pFileSaveAddress) {
                __memory pCurrInstFileAddress = ud_obj.inp_buff - ud_obj.inp_ctr;
                /*
                 * 如果是内存访问操作
                 * 取出地址与跳转地址表中进行检索
                 */
                __address addrTargetAddress = (__address)(pCurrOperand->lval.sdword);
                __dword dwNowRva = GetNewRvaFromJmpAddressTable(addrTargetAddress, &JmpTableToAddressList, iJmpAddressTableCount);
                if (dwNowRva != __NOT_IN_JMPADDRESSTABLE__) {
                    addrNowAddress = addrImageBase + dwNowRva;
                    *(__address *)pFileSaveAddress = addrNowAddress;//重新设置
 
                    // 设置一个引入表引用结构
                    (*pCurrReferenceImportTableAddresPoint) = (PREFERENCE_IMPORT_TABLE_ADDRESS)__logic_new__(REFERENCE_IMPORT_TABLE_ADDRESS, 1);
                    if (bOnFile) {
                        (*pCurrReferenceImportTableAddresPoint)->ofReferenceRVA = Raw2Rva(pMem, (__integer)(pFileSaveAddress - pMem));
                        (*pCurrReferenceImportTableAddresPoint)->addrReferenceMemAddress = addrImageBase + Raw2Rva(pMem, (__integer)(pCurrInstFileAddress - pMem));
                    } else {
                        (*pCurrReferenceImportTableAddresPoint)->ofReferenceRVA = (__integer)(pFileSaveAddress - pMem);
                        (*pCurrReferenceImportTableAddresPoint)->addrReferenceMemAddress = addrImageBase + (__integer)(pCurrInstFileAddress - pMem);
                    }
                    (*pCurrReferenceImportTableAddresPoint)->pReferenceFileAddress = pCurrInstFileAddress;
                    __logic_memcpy__(&((*pCurrReferenceImportTableAddresPoint)->ud_obj), &ud_obj, sizeof(ud_t));
 
                    // 增加引用引入表内存指令RVA,如果大于最大的计数则加密引入表失败直接退出
                    if (pImportProtect->iImportTableReferenceAddressCount >= __MAX_IMPORT_REFERENCE_COUNT__) {
                        // 释放已经分配的内存
                        ReleaseReferenceImportTableAddress(&pReferenceImportTableAddres);
                        return NULL;
                    }/* end if */
                    pImportProtect->ofImportTableReferenceAddressRVA[pImportProtect->iImportTableReferenceAddressCount] = (*pCurrReferenceImportTableAddresPoint)->ofReferenceRVA;
                    pImportProtect->ofAPINowRVA[pImportProtect->iImportTableReferenceAddressCount] = dwNowRva;
                    (pImportProtect->iImportTableReferenceAddressCount)++;
 
                    // 移动到下一个
                    pCurrReferenceImportTableAddresPoint = &((*pCurrReferenceImportTableAddresPoint)->pNext);
                }
            }/* end if */
        }/* end if */
    }
 
    pImportProtect->ofJmpTableRva = ofJmpTableRva;//设置新跳转表的RVA
    // 销毁原先的引入表
    if (bOnFile)
        DeleteDataDirectoryObject(pMem, IMAGE_DIRECTORY_ENTRY_IMPORT);
    else
        DeleteDataDirectoryObjectOnMemMap(pMem, IMAGE_DIRECTORY_ENTRY_IMPORT);
 
    return pReferenceImportTableAddres;
}
 
/*
 * 介绍:
 *    解密引入地址表,此函数在目标文件中调用,用于修复
 *
 * 参数:
 *    pArg:力量解密引入表参数结构
 */
__bool __API__ PowerDecryptImportTable(PPOWERDECRYPTIMPORTTABLE_ARG pArg) {
    PIMPORT_PROTECT pImportProtect = NULL;
    FPAddThunkCodeStub pAddThunkCodeStub = NULL;
    __byte bXor = 0;
    HMODULE hDll = NULL, hCurrDll = NULL;
    __integer i = 0, j = 0, iIndex = 0;
    __integer iLength = 0;
    __char *pLibName = NULL;
    __char LibName[64] = {0};
    __dword dwLibNameCrc32 = 0;
    __bool bDllIsProtect = FALSE;
 
    __PrintDbgInfo_OutputDbgString__("Entry PowerDecryptImportTable");
 
    // 初始化数据
    pImportProtect = pArg->pImportProtect;
    pAddThunkCodeStub = pArg->pAddThunkCodeStub;
    bXor = pImportProtect->bXor;//获取密钥的解密密码
 
    for (i = 0; i < pImportProtect->iLibraryKeyCount; i++) {
        __dword dwKey = 0;
        __memory pKey = NULL;
 
        dwKey = pImportProtect->dwLibraryKeyList[i];//解密密钥
        pKey = (__memory)&dwKey;
 
        XorKey4Bytes(pKey, bXor);
        iLength = pImportProtect->iLibraryNameLengthList[i];
        __logic_memset__(LibName, 0, 64);
        pLibName = pImportProtect->LibraryNameList[i];
        XorArray(dwKey, (__memory)pLibName, (__memory)LibName, iLength);//解密
 
        // 获取库名的CRC32值
        dwLibNameCrc32 = crc32((__memory)LibName, iLength);
 
        // 加载并重映射DLL
        hCurrDll = g_pLoadLibraryA(LibName);
 
        // 如果是在保护内的库则重新映射
        if (ThisValueIsInList(dwLibNameCrc32, pImportProtect->dwProtectDllCrc32List, pImportProtect->iProtectDllCrc32Count)) {
            // 查看是否是排除在执行DllMain的库
            if (ThisValueIsInList(dwLibNameCrc32, pImportProtect->dwProtectDllCallDllMainCrc32List, pImportProtect->iProtectDllCallDllMainCrc32Count))
                hDll = (HMODULE)RemapDll((__memory)hCurrDll, g_pVirtualAlloc, TRUE);
            else
                hDll = (HMODULE)RemapDll((__memory)hCurrDll, g_pVirtualAlloc, FALSE);
 
            // 设置此DLL经过保护
            bDllIsProtect = TRUE;
        } else {
            hDll = (HMODULE)hCurrDll;
 
            // 设置此DLL未经过保护
            bDllIsProtect = FALSE;
        }
 
        // 获取API地址
        for (j = 0; j < pImportProtect->iApiNumberInThisLibrary[i]; j++) {
            __memory pHashData = NULL;
            __address addrImageBase = 0;
            __dword dwFirstThunk = 0;
            __address *paddrOut = NULL;
 
            pHashData = (__memory)&(pImportProtect->dwApiNameCrc32List[iIndex]);
            addrImageBase = pImportProtect->addrImageBase;
            dwFirstThunk = pImportProtect->dwFirstThunkList[iIndex];
            paddrOut = (__address *)(addrImageBase + (__address)dwFirstThunk);
 
            if (pImportProtect->bIsOrdList[iIndex]) {
                __dword dwOrd = pImportProtect->dwApiNameCrc32List[iIndex] & 0xFFFF;//取低2字节
                __PrintDbgInfo_OutputDbgString__("Already goto xGetProcAddressByHash by API ord");
                *paddrOut = (__address)xGetProcAddressByHash(hDll, (__memory)dwOrd, 2, DecrypterHashFunc);
            } else {
                __PrintDbgInfo_OutputDbgString__("Already goto xGetProcAddressByHash by API name hash value");
                *paddrOut = (__address)xGetProcAddressByHash(hDll, pHashData, sizeof(__address), DecrypterHashFunc);
            }
 
            // 在需要抽取的API列表中找寻
            __PrintDbgInfo_OutputDbgString__("Already goto ThisApiIsInProtectList");
            if (ThisValueIsInList(pImportProtect->dwApiNameCrc32List[iIndex], &(pImportProtect->dwProtectApiCrc32List), pImportProtect->iProtectApiCrc32Count)) {
                __memory pNowAddress = NULL;
                __memory pNewAddress = NULL;
                __offset ofOffset = 0;
                //__integer iProcSize = 0;
 
                pNowAddress = (__memory)(*paddrOut);
 
                // 计算这个函数的长度
                //iProcSize = SimpleCalcThisProcedureLength(pNowAddress);
 
                if (pAddThunkCodeStub) {
                    pNewAddress = pAddThunkCodeStub((__address)pNowAddress);
                    if (!pNewAddress) goto _default_add_thunk_code_stub;//如果为空则直接转入默认处理
                } else {
                    _default_add_thunk_code_stub:
                    // 产生一个中间函数
                    pNewAddress = __logic_new_size__(0x10);
                    // 计算偏移
                    ofOffset = CalcCurrOffsetFromAddress(32, (__address)pNowAddress, (__address)pNewAddress, 5);
                    *(__byte *)pNewAddress = 0xE9;
                    *(__offset *)(pNewAddress + 1) = ofOffset;
                }
 
                // 重新设定地址
                *paddrOut = (__address)pNewAddress;
            }
 
            // 增加索引计数
            iIndex++;
        }/* end for */
 
        // 如果在保护范围内则清除这个DLL的无用信息
        if (bDllIsProtect) {
            __PrintDbgInfo_OutputDbgString__("Already goto ClearRemapDllUnSafeInfo");
            ClearRemapDllUnSafeInfo(hDll);
        }/* end if */
    }
 
    // 检验
    if (iIndex != pImportProtect->iApiNameCrc32Count)
        return FALSE;
 
    // 这里开启一个非常重要就是修订目标代码节要引用的
    __PrintDbgInfo_OutputDbgString__("Fix target code reference API memory address");
    {
        __integer i = 0;
        __memory pMem = NULL;
         
        pMem = (__memory)(pImportProtect->addrImageBase);
 
        for (i = 0; i < pImportProtect->iImportTableReferenceAddressCount; i++) {
            __address *pReference = NULL;
            __address addrNowAddress = 0;
 
            // 获得引用的地址
            pReference = (__address *)(pMem + pImportProtect->ofImportTableReferenceAddressRVA[i]);
            addrNowAddress = (__address)(pMem + pImportProtect->ofAPINowRVA[i]);
 
            // 设置
            *pReference = addrNowAddress;
        }/* end for */
    }
 
    __PrintDbgInfo_OutputDbgString__("Exit PowerDecryptImportTable");
    return TRUE;
}
2012-8-14 14:18
0
雪    币: 125
活跃值: (171)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
LS碉堡了。。。
2012-8-15 09:40
0
雪    币: 81
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
Mark~ 看下版主思路~
2012-8-15 09:49
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册