首页
社区
课程
招聘
[分享]Debug<<软件加密技术内幕>>--<<软件加密技术内幕>>读后感三篇
发表于: 2008-3-24 16:42 5987

[分享]Debug<<软件加密技术内幕>>--<<软件加密技术内幕>>读后感三篇

2008-3-24 16:42
5987
Debug<<软件加密技术内幕>>--<<软件加密技术内幕>>读后感三篇

    所谓Debug<<软件加密技术内幕>>也就是找出书中有不太完善的地方,或者说我对书中有疑问的地方.我读<<软件加密技术内幕>>有一段时间了,重点看了第一章,第二章,第三章,第四章前半部分,第六章前半部分,感觉书写得很经典!我在这里提出一些自己的看法,希望对其他读者有点帮助,贻笑大方了.

    1.第一章15页表1-5的IMAGE_SECTION_HEADER结构少了一个字段:PointerToLinenumbers.
    2.第三章77页表3-3的tElock0.98特征数据不符合附书源码中的加壳记事本,而应该是:
编号 异常地址
1 0x0040DA1D
2 0x0040DA74
3 0x0040C08C
4 0x0040C090
5 0x0040C099
6 0x0040C09E
7 0x0040C0A3
8 0x0040C0A7
9 0x0040C6A8
10 0x0040CAA1
11 0x0040CAE4
12 0x0040CB27
13 0x0040CB67
14 0x0040CBA6
15 0x0040CBF0
16 0x0040CE0D
17 0x0040CE49
18 0x0040D6F1
19 0x0040D7E1
20 0x0040D817

   编号为:3,15,18的SHE发生地址是固定的.
我在"tElock0.98脱壳--<<软件加密技术内幕>>读后感二篇 "中有所指出,但是对于不同的tElock版本可能又不同,我这里仅仅针对附书源码中的加壳记事本.

    3.第三章94页第一行"图中的SF标志就是Single Step"标志了",应该是""图中的TF标志就是Single Step"",因为SF是符号为标志.

    4.第六章第一节的"外壳编写基础"附书源码.
    (1).BUG1.
    书中有两处使用区块表名来判断是否是特殊区块表,如:

    cmp    dword ptr [esi], 'ade.'
    jz    MergeSectionOver
    cmp    dword ptr [esi], 'rsr.'
    jz    MergeSectionOver
    cmp    dword ptr [esi], 'oci.'
    jz    MergeSectionOver

但是如果对于一个程序,将其资源区块表名改为".r",那么我们的程序就会崩溃.这一点我验证了,可以按如下方法解决:
靠数据目录表来定位出特殊区块的RVA值并保存之,在遍历区块表时,将VirtualAddress字段与保存的特殊区块的RVA比较,如果相同则跳过.如:

    mov    eax,[esi].VirtualAddress
    cmp    eax,dwRsrRva
    jz    MergeSectionOver

    (2)BUG2
    较多地使用了区块表的Misc.VirtualSize,然而没有配合SizeOfRawData字段使用,有时程序也会崩溃.因为Misc.VirtualSize字段在文件中的含义是文件的实际字节数,然而它并不可靠,如对于'CODE','DATA',等区块来说它根本就没有用,
我试着将'CODE','DATA'区块表的Misc.VirtualSize清零,程序仍然可以正确加载,因为这时有用的是SizeOfRawData字段的值.但是只靠SizeOfRawData字段也是不可靠的,因为对于'BSS','.tls'区块来说,SizeOfRawData字段值为0,而这时Misc.VirtualSize便起到重要的作用了.所以仅仅只靠这两个字段中的一个是不够的,要配合起来使用,如:

    mov    eax,[edi].Misc.VirtualSize   
    .if    eax==0
        mov    eax,[edi].SizeOfRawData
    .endif

这样使用就比较安全了,但也不是绝对的.

    (3)小技巧1

;********************在消息框中增加一行消息输出************************************
AddLine        PROC    LineToAdd: DWORD
LOCAL    LineLength:DWORD
    pusha
    mov    esi,LineToAdd
    xor    eax,eax
getlinelength:
    cmp    byte ptr [esi],0
    jz    Lengthgetted
    inc    eax
    inc    esi
    jmp    getlinelength
Lengthgetted:   
    mov    LineLength, eax
    mov    edi, MessageBufferAddr   
    add    edi, DebugMsgSize
    mov    esi, LineToAdd
    mov    ecx, LineLength
    push    ecx
    shr    ecx, 2
    cld
    rep    movsd
    pop    ecx
    and     ecx, 3
    rep    movsb
    mov    dword ptr [edi], 00000A0Dh
    mov    eax, LineLength
    add    DebugMsgSize, eax
    add    DebugMsgSize, 2
    invoke    SetDlgItemText, hProtDlg, IDC_MESSAGEBOX_EDIT, MessageBufferAddr
    invoke    SendDlgItemMessage, hProtDlg, IDC_MESSAGEBOX_EDIT, EM_GETLINECOUNT, 0, 0
    dec     eax
    invoke    SendDlgItemMessage, hProtDlg, IDC_MESSAGEBOX_EDIT, EM_LINESCROLL, 0, eax
    popa
    ret
AddLine        endp
;*****************************************************

可以改为:

;-------------------------------------------------
;向信息框里追加信息,参数lpMsg是信息串地址,使用了一个全局句柄:hEditInfo
_AddLine    proc    lpMsg
    pushad
    invoke    SendMessage,hEditInfo,EM_SETSEL,-1,0
    invoke    SendMessage,hEditInfo,EM_REPLACESEL,0,lpMsg
    popad
    ret
_AddLine endp
;-------------------------------------------------

这样更加简练呵,原理是:将光标置于文本末尾,"替换掉"末尾的文本(实际没有选择任何文本),就实现了追加文本的效果,不过定义的字符串后面要有:0DH,0AH,0,因为要实现换行的.

    (4)小技巧2

    .if    eax == WM_INITDIALOG    ;选项对话框初始化
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_issaveset,0h,addr IniFileName
        .if    eax == 1
            mov    IsSaveSet,1
            invoke    CheckDlgButton,OptionhWnd,IDC_SAVESET,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_iscreatebak,0h,addr IniFileName
        .if    eax == 1
            mov    IsCreateBak,1
            invoke    CheckDlgButton,OptionhWnd,IDC_CREATEBAK,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_Ispackres,0h,addr IniFileName
        .if    eax == 1
            mov    IsPackRes,1
            invoke    CheckDlgButton,OptionhWnd,IDC_PACKRES,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_Issavesdata,0h,addr IniFileName
        .if    eax == 1
            mov    IsSaveSData,1
            invoke    CheckDlgButton,OptionhWnd,IDC_SDATA,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_Iscodeprot,1h,addr IniFileName
        .if    eax == 1
            mov    IsCodeProt,1
            invoke    CheckDlgButton,OptionhWnd,IDC_CODEPROT,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_Clssecname,1h,addr IniFileName
        .if    eax == 1
            mov    IsClsSecName,1
            invoke    CheckDlgButton,OptionhWnd,IDC_CLSSECNAME,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_Ismergesection,1h,addr IniFileName
        .if    eax == 1
            mov    IsMergeSection,1
            invoke    CheckDlgButton,OptionhWnd,IDC_MERGESECTION,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_Isprotimptable,1h,addr IniFileName
        .if    eax == 1
            mov    IsProtImpTable,1
            invoke    CheckDlgButton,OptionhWnd,IDC_APIPROT,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_IsReFileHead,1h,addr IniFileName
        .if    eax == 1
            mov    IsReFileHead,1
            invoke    CheckDlgButton,OptionhWnd,IDC_REFILEHEAD,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_IsFileAlignment200,1h,addr IniFileName
        .if    eax == 1
            mov    IsFileAlignment200,1
            invoke    CheckDlgButton,OptionhWnd,IDC_FA200,BST_CHECKED
        .endif
        invoke    GetPrivateProfileInt,addr IniSectionName,addr I_IsNoRelocation,1h,addr IniFileName
        .if    eax == 1
            mov    IsNoRelocation,1
            invoke    CheckDlgButton,OptionhWnd,IDC_NOREL0,BST_CHECKED
        .endif

以及

;***************保存设置***************************
SaveTheSet    PROC
    pushad
    .if    IsSaveSet == 1
        .if    IsSaveSet == 1
            inc    I_issaveset_D
        .endif
        .if    IsCreateBak == 1
            inc    I_iscreatebak_D
        .endif
        .if    IsMergeSection == 1
            inc    I_Ismergesection_D
        .endif
        .if    IsPackRes == 1
            inc    I_Ispackres_D
        .endif
        .if    IsSaveSData == 1
            inc    I_Issavesdata_D
        .endif
        .if    IsProtImpTable == 1
            inc    I_Isprotimptable_D
        .endif
        .if    IsCodeProt == 1
            inc    I_Iscodeprot_D
        .endif
        .if    IsClsSecName == 1
            inc    I_Clssecname_D
        .endif
        .if    IsReFileHead == 1
            inc    I_IsReFileHead_D
        .endif
        .if    IsFileAlignment200 == 1
            inc    I_IsFileAlignment200_D
        .endif
        .if    IsNoRelocation == 1
            inc    I_IsNoRelocation_D
        .endif
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_issaveset,addr I_issaveset_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_iscreatebak,addr I_iscreatebak_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_Ispackres,addr I_Ispackres_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_Issavesdata,addr I_Issavesdata_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_Iscodeprot,addr I_Iscodeprot_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_Clssecname,addr I_Clssecname_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_Ismergesection,addr I_Ismergesection_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_Isprotimptable,addr I_Isprotimptable_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_IsReFileHead,addr I_IsReFileHead_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_IsFileAlignment200,addr I_IsFileAlignment200_D,addr IniFileName
        invoke    WritePrivateProfileString,addr IniSectionName,addr I_IsNoRelocation,addr I_IsNoRelocation_D,addr IniFileName
    .endif
    popad
    ret
SaveTheSet    endp

是实现选项的加载与保存的,我实现的方法如下:
;-------------------------------------------------
;加载设置
invoke    CreateFile,offset szIniFileName, GENERIC_READ,\
                FILE_SHARE_READ,0, 3,FILE_ATTRIBUTE_NORMAL,NULL
    push    eax
    invoke    ReadFile,eax,offset dwSettings,4*(IDC_CHK_END - IDC_CHK_START + 1),offset dwBytesOfRW,NULL
    pop    eax
    invoke    CloseHandle,eax

    lea    esi,dwSettings
    mov    edi,IDC_CHK_START
    mov    ecx,IDC_CHK_END - IDC_CHK_START + 1
@@:
    push    ecx
    lodsd
    invoke    CheckDlgButton,hWnd,edi,eax
    inc    edi
    pop    ecx
    loop    @B
;-------------------------------------------------
;保存设置
    invoke    CreateFile,offset szIniFileName, GENERIC_WRITE,\
                FILE_SHARE_READ,0, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL
        push    eax
        invoke    WriteFile,eax,offset dwSettings,4*(IDC_CHK_END - IDC_CHK_START + 1),offset dwBytesOfRW,NULL
        pop    eax
        invoke    CloseHandle,eax

;-------------------------------------------------

(5)小技巧3

.if    eax == IDC_OPTIONOK
            ;*******创建备份吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_CREATEBAK, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsCreateBak,1
            .else
                mov    IsCreateBak,0
            .endif
            ;*******清空段名吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_CLSSECNAME, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsClsSecName,1
            .else
                mov    IsClsSecName,0
            .endif
            ;*******合并区段吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_MERGESECTION, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsMergeSection,1
            .else
                mov    IsMergeSection,0
            .endif
            ;********压缩资源吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_PACKRES, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsPackRes,1
            .else
                mov    IsPackRes,0
            .endif
            ;********保留额外数据吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_SDATA, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsSaveSData,1
            .else
                mov    IsSaveSData,0
            .endif
            ;*******输入表加密吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_APIPROT, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsProtImpTable,1
            .else
                mov    IsProtImpTable,0
            .endif
            ;*******重算文件头大小吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_REFILEHEAD, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsReFileHead,1
            .else
                mov    IsReFileHead,0
            .endif
            ;*******强制文件对齐为200吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_FA200, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsFileAlignment200,1
            .else
                mov    IsFileAlignment200,0
            .endif
            ;*******去处重定位数据吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_NOREL0, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsNoRelocation,1
            .else
                mov    IsNoRelocation,0
            .endif

            ;********特殊代码加密吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_CODEPROT, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsCodeProt,1
            .else
                mov    IsCodeProt,0
            .endif
            ;********保存设置吗?
            invoke    SendDlgItemMessage, OptionhWnd, IDC_SAVESET, BM_GETCHECK, 0, 0
            .if    eax == BST_CHECKED
                mov    IsSaveSet,1
            .else
                mov    IsSaveSet,0
            .endif

        .endif

是选择CheckBox时的事件处理代码,可以改写为:

;-------------------------------------------------
mov eax,wParam
    .if ax>=IDC_CHK_START && ax<=IDC_CHK_END
        lea    edi,dwSettings
        mov    ecx,eax
        sub    ecx,IDC_CHK_START
        shl    ecx,2
        add    edi,ecx
        invoke    SendDlgItemMessage, hWnd, eax, BM_GETCHECK, 0, 0
        stosd
    .endif
;-------------------------------------------------

(6)小技巧4

打开文件:

.if eax == IDC_OPEN_BUTTON    ;是打开文件命令吗?
            invoke    RtlZeroMemory,MessageBufferAddr,1000h
            mov    DebugMsgSize,0
            invoke    RtlZeroMemory,OFFSET FileName,MAXSIZE    ;清空文件名缓冲
            mov    Openfilename.lStructSize,SIZEOF Openfilename
            push    ProthWnd
            pop    Openfilename.hWndOwner
            push    hInst
            pop    Openfilename.hInstance
            mov    Openfilename.lpstrFilter, OFFSET FilterString
            mov    Openfilename.lpstrFile, OFFSET FileName
            mov    Openfilename.nMaxFile,MAXSIZE
            mov    Openfilename.Flags, OFN_FILEMUSTEXIST or \
                OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                OFN_EXPLORER or OFN_HIDEREADONLY
            invoke    GetOpenFileName, ADDR Openfilename
                .IF eax==TRUE        ;文件打开成功
                    invoke    SetDlgItemText,ProthWnd,IDC_FILE_EDIT,ADDR FileName
                    invoke    FileIsExe    ;是合法的PE-EXE文件吗?
                    .if    eax==1
                        invoke    EnableWindow, hProtButton, TRUE
                    .else
                        invoke    EnableWindow, hProtButton, FALSE
                    .endif
                .ENDIF
......

可以写成一个独立的函数:

;-------------------------------------------------
;打开PE文件,参数:hWinMain为主窗体句柄
;lpfilebuff为文件名缓冲区
;lpext文件默认扩展名
;lpfilter过滤器
_OpenFile    proc lpfilebuff,lpfilter,lpext
local @stOF:OPENFILENAME

invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
push    lpfilter
pop @stOF.lpstrFilter
push    lpfilebuff
pop @stOF.lpstrFile
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
push    lpext
pop @stOF.lpstrDefExt
invoke    GetOpenFileName,addr @stOF
ret
_OpenFile    endp
;-------------------------------------------------

(7)小技巧5

;***************移动字符串***************************
MoveString    PROC    SourceStringADDR:DWORD,ObjectStringADDR:DWORD
;将源地址指向的以'00'结尾的字符串复制到目标地址指向的空间,并加密
;除eax外所有寄存器都不变,输出eax的值为复制的字节数
    push    edi
    push    esi
    push    ecx
    mov    edi,ObjectStringADDR
    mov    esi,SourceStringADDR
    xor    eax,eax
    xor    ecx,ecx
MoveNextByte:
    lodsb
    .if    eax!=0
        stosb
        inc    ecx
    .else
        jmp    AllByteMoved
    .endif
    xor    eax,eax
    jmp    MoveNextByte
AllByteMoved:
    mov    eax,ecx
    pop    ecx
    pop    esi
    pop    edi
    ret
MoveString    endp
;********************清除一个字符串********************************
ClsString    PROC    SourceStringADDR:DWORD
;将一个以'00'结束的字符串都清为'00'
    push    esi
    push    edi
    push    ecx
    mov    esi,SourceStringADDR
    mov    edi,SourceStringADDR
    xor    eax,eax
    xor    ecx,ecx
ClsNextByte:
    lodsb
    .if    eax!=0
        xor    al,al
        stosb
        inc    ecx
    .else
        jmp    AllByteCls
    .endif
    xor    eax,eax
    jmp    ClsNextByte
AllByteCls:
    mov    eax,ecx
    pop    ecx
    pop    edi
    pop    esi
    ret
ClsString    endp

改进:MoveString可以将字符串末尾的空字符(NULL),也一并复制过去,字符串长度包含0.这样较好,调用者就不必关心字符串后面的结束符0了.

;***************移动字符串***************************
MoveString    PROC    uses esi edi ecx lpStrSrc:DWORD,lpStrDst:DWORD
;将源地址指向的以'00'结尾的字符串复制到目标地址指向的空间,并加密
;除eax外所有寄存器都不变,输出eax的值为复制的字节数

    mov    edi,lpStrDst
    mov    esi,lpStrSrc
    xor    ecx,ecx
MoveNextByte:
    lodsb
    test     al,al
    jz    @Over
    stosb
    inc    ecx
    jmp    MoveNextByte
@Over:
    stosb    ;存储最后一个0
    inc    ecx
    mov    eax,ecx

    ret
MoveString    endp
;********************清除一个字符串********************************
ClsString    PROC    lpStr
;将一个以'00'结束的字符串都清为'00'
    pushad
    mov    esi,lpStr
    mov    edi,lpStr
ClsNextByte:
    lodsb
    test    al,al
    jz    @Over
    xor    al,al
    stosb
    jmp    ClsNextByte
@Over:
    popad
    ret
ClsString    endp

(8)小技巧6

;***************产生垃圾指令***********************
MakeFunkCode    PROC    FuncCodeBase:DWORD
LOCAL    FunkCodeSize:DWORD
    pushad
    mov    FunkCodeSize,0h
    mov    ecx,100h
    mov    edi,FuncCodeBase
MakeNextFunkCode:
    push    ecx
    rdtsc
    and    eax,7h
    .if    eax == 0
        lea    esi,Junk_Code_1_Start
        mov    ecx,Junk_Code_1_End-Junk_Code_1_Start
        add    FunkCodeSize,ecx
        rep    movsb
    .elseif    eax == 1
        lea    esi,Junk_Code_2_Start
        mov    ecx,Junk_Code_2_End-Junk_Code_2_Start
        add    FunkCodeSize,ecx
        rep    movsb
    .elseif    eax == 2
        lea    esi,Junk_Code_3_Start
        mov    ecx,Junk_Code_3_End-Junk_Code_3_Start
        add    FunkCodeSize,ecx
        rep    movsb
    .elseif    eax == 3
        lea    esi,Junk_Code_4_Start
        mov    ecx,Junk_Code_4_End-Junk_Code_4_Start
        add    FunkCodeSize,ecx
        rep    movsb
    .elseif    eax == 4
        lea    esi,Junk_Code_5_Start
        mov    ecx,Junk_Code_5_End-Junk_Code_5_Start
        add    FunkCodeSize,ecx
        rep    movsb
    .elseif    eax == 5
        lea    esi,Junk_Code_6_Start
        mov    ecx,Junk_Code_6_End-Junk_Code_6_Start
        add    FunkCodeSize,ecx
        rep    movsb
    .elseif    eax == 6
        lea    esi,Junk_Code_7_Start
        mov    ecx,Junk_Code_7_End-Junk_Code_7_Start
        add    FunkCodeSize,ecx
        rep    movsb
    .elseif    eax == 7
        lea    esi,Junk_Code_8_Start
        mov    ecx,Junk_Code_8_End-Junk_Code_8_Start
        add    FunkCodeSize,ecx
        rep    movsb
    .endif
    xor    eax,eax
    pop    ecx
    dec    ecx
    jnz    MakeNextFunkCode
    popad
    mov    eax,FunkCodeSize
    ret
MakeFunkCode    endp

由于代码很多有重复的,可以使用宏实现,不过我不推荐使用宏,改个组织结构:

;***************产生垃圾指令***********************
MakeFunkCode    PROC    FuncCodeBase:DWORD
LOCAL    @FuckCodeSize:DWORD
    pushad
    and    @FuckCodeSize,0h
    mov    ecx,100h
    mov    edi,FuncCodeBase
@@:
    push    ecx
    rdtsc
    and    eax,7h

    lea    esi,lpFuckCode
    shl    eax,3
    add    esi,eax
    mov    ecx,dword ptr[esi+4]
    add    @FuckCodeSize,ecx
    mov    esi,dword ptr[esi]
    rep    movsb

    pop    ecx
    loop    @B

    popad
    mov    eax,@FuckCodeSize
    ret
MakeFunkCode    endp

lpFuckCode     equ this    dword
FuckCode1_Addr        dd    Junk_Code_1_Start
FuckCode1_Size        dd    Junk_Code_1_End - Junk_Code_1_Start
FuckCode2_Addr        dd    Junk_Code_2_Start
FuckCode2_Size        dd    Junk_Code_2_End - Junk_Code_2_Start
FuckCode3_Addr        dd    Junk_Code_3_Start
FuckCode3_Size        dd    Junk_Code_3_End - Junk_Code_3_Start
FuckCode4_Addr        dd    Junk_Code_4_Start
FuckCode4_Size        dd    Junk_Code_4_End - Junk_Code_4_Start
FuckCode5_Addr        dd    Junk_Code_5_Start
FuckCode5_Size        dd    Junk_Code_5_End - Junk_Code_5_Start
FuckCode6_Addr        dd    Junk_Code_6_Start
FuckCode6_Size        dd    Junk_Code_6_End - Junk_Code_6_Start
FuckCode7_Addr        dd    Junk_Code_7_Start
FuckCode7_Size        dd    Junk_Code_7_End - Junk_Code_7_Start
FuckCode8_Addr        dd    Junk_Code_8_Start
FuckCode8_Size        dd    Junk_Code_8_End - Junk_Code_8_Start

还在完善中,总之改过后生成的程序小了很多,而且加壳过后的程序也小了不少,继续努力!
永远支持看雪!
                                                        by Sing

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 557
活跃值: (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
初步认为楼主很彪悍
2008-3-24 16:58
0
雪    币: 44229
活跃值: (19950)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
感谢你反馈的这些bug,有些bug估计是Hying想偷懒,如用'rsr.'来判断是不是资源区块。

第三版外壳编写部分,是直接将这章搬过去,所不同的是,将原来的asm直接翻译成VC来描写主程序编写,估计相应的bug还是存在。
2008-3-24 17:27
0
雪    币: 297
活跃值: (27)
能力值: ( LV13,RANK:380 )
在线值:
发帖
回帖
粉丝
4
不可靠!
《色戒》: 女人不可靠
《苹果》: 男人不可靠
《投名状》:兄弟也不可靠
《集结号》:组织更不可靠

《windows》

所有节名通通不可靠,要看节的属性或数据目录
CODE, DATA, BSS,这些节名不可靠,要看节的属性
TLS, RSRC节名不可靠,要看数据目录中相关表项

VirtualSize不可靠, SizeOfRawData总可靠
计算VirtualSize,最好用(Next VirtualAddress - Current VirtualAddress)

---------------------引用
“”“我试着将'CODE','DATA'区块表的Misc.VirtualSize清零,程序仍然可以正确加载,因为这时有用的是SizeOfRawData 字段的值.但是只靠SizeOfRawData字段也是不可靠的,因为对于'BSS','.tls'区块来说,SizeOfRawData字段值为0,而这时Misc.VirtualSize便起到重要的作用了.所以仅仅只靠这两个字段中的一个是不够的,要配合起来使用,如:
---------------------引用
VirtualSize之所以能清零,是因为loader在验证程序是否合法时,当VirtualSize小于SizeOfRawData时,VirtualSize取SizeOfRawData,在你的程序中,碰巧,SizeOfRawData满足下面的公式。
不管怎么样,在对齐后,VirtualSize必须等于Current VirtualAddress - Next VirtualAddress,否则出现错误提示对话框。
这也解释了你得出的结论之一:SizeOfRawData取零时,VirtualSize可靠。
2008-3-24 17:46
0
雪    币: 186
活跃值: (15)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
5
谢谢tnttools的指点,也期待第三版...
2008-3-24 19:24
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
6
楼主很强大。。
2008-3-24 19:42
0
雪    币: 201
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
LZ很厉害,学习了
2008-3-24 19:51
0
游客
登录 | 注册 方可回帖
返回
//