写在前面的话:
这篇关于建立PE 文件头的IDC 描述语言的代码和很早前发的那个 DELPHI.IDC 是同期作品,这个作品一只没有能够完成,有自己的原因,也有IDC所提供的函数的原因,在IDA中,你可以对一个结构的成员进行 OpOffEx 的操作,但在 IDC 中,对结构的建立却没有相应的参数,具体如下:

代码:
static ResourceStruct(ResBase) {   auto id;   id = AddStrucEx(-1,"IMAGE_RESOURCE_DIRECTORY_ENTRY_8_8",0);   id = GetStrucIdByName("IMAGE_RESOURCE_DIRECTORY_ENTRY_8_8");   AddStrucMember(id,"Name", 0X0,  0x20500400, ResBase, 4);   AddStrucMember(id,"DataIsDirectory",  0X4,  0x20500400, ResBase, 4); }   



下面是 IDA 在线帮助中对函数 AddStrucMember 的具体说明;
***********************************************
** add structure member
        arguments:      id      - structure type ID
                        name    - name of the new member
                        offset  - offset of the new member
                        flag    - type of the new member. Should be one of
                                  FF_BYTE..FF_PACKREAL (see above)
                                  combined with FF_DATA
                        typeid  - structure id if 'flag' == FF_STRU
                                  Denotes type of the member if the member
                                  itself is a structure. Otherwise should be
                                  -1.
                                  if isOff0(flag) then typeid specifies
                                  the offset base.
                                  if isASCII(flag) then typeid specifies
                                  the string type (ASCSTR_...).
                        nbytes  - number of bytes in the new member
        returns:        0 - ok, otherwise error code:
#define STRUC_ERROR_MEMBER_NAME   1     // already have member with this name (bad name)
#define STRUC_ERROR_MEMBER_OFFSET 2     // already have member at this offset
#define STRUC_ERROR_MEMBER_SIZE   3     // bad number of bytes or bad sizeof(type)
 
long AddStrucMember(long id,string name,long offset,long flag,
                    long typeid,long nbytes);

其中 flag 参数是我们主要研究的对象,flag 参数具体值如下:

第 9-10 位

#define MS_CLS  0x00000600L             // Mask for typing
#define FF_CODE 0x00000600L             // Code ?
#define FF_DATA 0x00000400L             // Data ?
#define FF_TAIL 0x00000200L             // Tail ?
#define FF_UNK  0x00000000L             // Unknown ?

第 20-23 位
#define MS_0TYPE 0x00F00000L            // Mask for 1st arg typing
#define FF_0VOID 0x00000000L            // Void (unknown)?
#define FF_0NUMH 0x00100000L            // Hexadecimal number?
#define FF_0NUMD 0x00200000L            // Decimal number?
#define FF_0CHAR 0x00300000L            // Char ('x')?
#define FF_0SEG  0x00400000L            // Segment?
#define FF_0OFF  0x00500000L            // Offset?
#define FF_0NUMB 0x00600000L            // Binary number?
#define FF_0NUMO 0x00700000L            // Octal number?
#define FF_0ENUM 0x00800000L            // Enumeration?
#define FF_0FOP  0x00900000L            // Forced operand?
#define FF_0STRO 0x00A00000L            // Struct offset?
#define FF_0STK  0x00B00000L            // Stack variable?

第 28-31 位
#define DT_TYPE 0xF0000000L             // Mask for DATA typing
#define FF_BYTE 0x00000000L             // byte
#define FF_WORD 0x10000000L             // word
#define FF_DWRD 0x20000000L             // dword
#define FF_QWRD 0x30000000L             // qword
#define FF_TBYT 0x40000000L             // tbyte
#define FF_ASCI 0x50000000L             // ASCII ?
#define FF_STRU 0x60000000L             // Struct ?
#define FF_OWRD 0x70000000L             // octaword (16 bytes)
#define FF_FLOAT 0x80000000L            // float
#define FF_DOUBLE 0x90000000L           // double
#define FF_PACKREAL 0xA0000000L         // packed decimal real
#define FF_ALIGN    0xB0000000L         // alignment directive

在我们这个例子中
0x20500400= FF_DATA | FF_0OFF | FF_DWRD

这个 Offset 的设置相当于:
OpOffEx(ea, 0, REF_OFF32, -1, ResBase, 0x0);

而我们需要的是类似下面的设置:
OpOffEx(ea, 0, REF_OFF32, -1, ResBase, 0x80000000);

因为这个问题,资源这部分的内容无法完成,当时就放下了,准备以后有时间在想个折中的办法,或者什么曲线救国的方法,这一拖,已过了半年,而我对IDC的那点理解也完全溢出了(已经完全忘记了,哈哈)。

现在将这个没有完工的东西拿出来,希望大家不要见笑,并希望有能力的兄弟继续完成这段东西。

说明:
这是用IDA的描述语言写的IDC文本,使用这段描述语言,对IDA在加载可执行文件时有一定的要求。在IDA加载文件时的 Load a New file 对话框有如下的选择:
1、Load Resource 前打勾;
2、Manual Load 前打勾;
3、Make Imports Segment 不打勾;

注:如果你没有修改 IDA.CFG 文件,IDA 缺省是不加载头文件的,也不加载资源文件,并对输入表建立一个虚拟的输入表段,这样,我们的这个描述语言将无法正确工作。

目的:
这篇文章是为了帮助那些希望理解PE文件格式的读者,这个IDC对于真正的破解并没有什么具体的帮助。一个可执行文件经过这个IDC整理之后,将建立非常直观的PE文件头和相应的输入表,输出表,延时输入表,捆绑输入表,调试输入表,(资源表没有建立)。用这种格式观察PE文件结构和相应的输入输出表,有助你对这些结构的深入理解,我们大多使用的PE工具给出的是一个非常抽象的和经过删节的PE结构。在IDA中你所见到的PE结构是在内存中的真实的影像,理解这些,对于你有志写自己的PE结构方面的程序或文章,无疑会提供许多帮助。

附件说明
附加中有两个htm文件显示了经过这个IDC整理后的结果,和 CreatePEHead.IDC

单击此处打开附件:idc.rar