| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 870 人关注过本帖, 1 人收藏
标题:为什么会报病毒,是个加密程序
只看楼主 加入收藏
u332744
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-11
结帖率:75%
收藏(1)
已结贴  问题点数:18 回复次数:10 
为什么会报病毒,是个加密程序
;*********************************************************
;程序名称:LC Crypto
;          本文件只是主程序的源代码
;          注意加密部分的代码是在 attach.asm
;          本程序综合运用了SEH、PE、CRC32知识
;作者:罗聪
;日期:2002-11-29
;整理:2003-3-2
;出处:http://www.(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“老罗的缤纷天地”(http://www.
;>> 在此特别强烈感激 俄罗斯 的 Comrade 大虾,
;>> 跟他的交流使我受益匪浅,他的源代码更使我汗颜!
;*********************************************************


.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\shell32.inc
include \masm32\include\comdlg32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\comdlg32.lib

;*********************************************************
;很有用的宏
;*********************************************************
CTEXT    MACRO y:VARARG
    LOCAL sym
    CONST segment
    ifidni <y>,<>            
        sym db 0        
    else            
        sym db y,0
    endif
    CONST ends
    exitm <offset sym>
ENDM

m2m MACRO M1, M2
    push M2
    pop    M1
ENDM

;*********************************************************
;子程序定义
;*********************************************************
WndProc                    proto    :DWORD, :DWORD, :DWORD, :DWORD
Protect                    proto
ErrorHandler            proto C    :DWORD, :DWORD, :DWORD, :DWORD
ExceptionFilter            proto    :DWORD
AboutProc                proto    :DWORD, :DWORD, :DWORD, :DWORD
init_crc32table_m        proto
arraycrc32_m            proto

;*********************************************************
;常量定义
;*********************************************************
.const
IDI_LC                    equ    1
IDC_BUTTON_BROWSE        equ    3000
IDC_EDIT_FILENAME        equ    3001
IDC_EDIT_PASSWORD        equ    3002
IDC_CHECKBOX_KEEPBACKUP    equ    3003
IDC_BUTTON_PROCESS        equ    3004
IDC_BUTTON_ABOUT        equ    3005
IDC_BUTTON_EXIT            equ    3006
IDC_BUTTON_HELP            equ    3007
IDC_BUTTON_HOMEPAGE        equ    3008
DLG_HELP                equ    3009
IDC_EDIT_PASSWORD_2        equ    3010
IDM_MENU_ABOUT            equ    3011

;*********************************************************
;变量定义
;*********************************************************
.data
szDlgName                db    "LC_DIALOG", 0
szCaption                db    "LC Crypto :: v0.1 by LC", 0
szMenuAbout                db    "&About LC Crypto...", 0
szFileFilter            db    "Executables (*.exe)", 0, "*.exe", 0, 0
szStatusDone            db    "Done!", 0
szError                    db    "Error", 0
szErrorThread            db    "Error at %08Xh", 13, 10, "Registers:", 13, 10, "eax = %08Xh ebx = %08Xh ecx = %08Xh", 13, 10, "edx = %08Xh esp = %08Xh ebp = %08Xh", 13, 10, "esi = %08Xh edi = %08Xh", 13, 10, 13, 10, "Recovering...", 0
szErrorFinal            db    "Error at %08Xh", 13, 10, "Quitting...", 0

;*********************************************************
;插入宿主的代码
;*********************************************************
include attach.asm

;*********************************************************
;未初始化的变量定义
;*********************************************************
.data?
hFile                    dd                        ?
szMessage                db                        256 dup (?)
SEH                        dd                        6 dup (?)

data_start                equ                        $
mbp                        MSGBOXPARAMS            <>
ofn                        OPENFILENAME            <>
img_dos_hdr                IMAGE_DOS_HEADER        <>
img_nt_hdrs                IMAGE_NT_HEADERS        <>
img_sect_hdr            IMAGE_SECTION_HEADER    <>
szFileName                db                        MAX_PATH dup (?)
szFileNameBak            db                        MAX_PATH dup (?)
szPassword                db                        16 dup (?)
szPassword_2            db                        16 dup (?)
data_size                equ                        $ - data_start
bNew                    db                        attach_size dup (?)
hInstance                dd                        ?
crc32tble                dd                        256 dup(?)    ;CRC-32 table

;*********************************************************
;代码段开始
;*********************************************************
.code
main:
    ;挂接异常处理模块:
    invoke    SetUnhandledExceptionFilter, addr ExceptionFilter
    push    edi
    xor        eax, eax
    mov        ecx, data_size shr 2
    mov        edi, data_start
    rep        stosd
    .if data_size and 3
        mov    edi, data_start
        mov    ecx, data_size and 3
        rep    stosb
    .endif
    pop    edi

    ;不用说了吧:
    invoke    GetModuleHandle, eax
    mov        hInstance, eax
    mov        mbp.hInstance, eax
    mov        ofn.hInstance, eax
    invoke    DialogBoxParam, eax, addr szDlgName, 0, addr WndProc, eax
    invoke    ExitProcess, eax

;*********************************************************
;主程序消息循环
;*********************************************************
WndProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
    .if uMsg == WM_CLOSE
        invoke    EndDialog, hWnd, 0

    .elseif uMsg == WM_INITDIALOG
        ;设置我的图标:
        invoke    LoadIcon, hInstance, IDI_LC
        invoke    SendMessage, hWnd, WM_SETICON, ICON_SMALL, eax

        ;默认“保留备份文件”选项是打钩的:
        invoke    CheckDlgButton, hWnd, IDC_CHECKBOX_KEEPBACKUP, BST_CHECKED

        ;储存hWnd,后面会用到:
        mov eax, hWnd
        mov    mbp.hwndOwner, eax
        mov    ofn.hwndOwner, eax

        ;在系统菜单中加入我的“关于”对话框:
        invoke    GetSystemMenu, eax, 0
        push    offset szMenuAbout
        push    IDM_MENU_ABOUT
        push    MFT_STRING
        push    eax
        invoke    AppendMenu, eax, MFT_SEPARATOR, 0, 0
        call    AppendMenu

        ;设置每个 Edit 框的最大文本输入字数:
        invoke    SendDlgItemMessage, hWnd, IDC_EDIT_FILENAME, EM_SETLIMITTEXT, sizeof szFileName, 0
        invoke    SendDlgItemMessage, hWnd, IDC_EDIT_PASSWORD, EM_SETLIMITTEXT, sizeof szPassword, 0
        invoke    SendDlgItemMessage, hWnd, IDC_EDIT_PASSWORD_2, EM_SETLIMITTEXT, sizeof szPassword_2, 0

    .elseif uMsg == WM_SYSCOMMAND
        .if    wParam == IDM_MENU_ABOUT
            ;打开“关于”对话框:
            invoke DialogBoxParam, hInstance, DLG_HELP, hWnd, offset AboutProc, 0
        .endif

    .elseif uMsg == WM_COMMAND
        mov    eax, wParam
        .if ax == IDC_BUTTON_BROWSE
            ;“打开文件”对话框:
            mov    ofn.lStructSize, sizeof ofn
            mov    ofn.lpstrFilter, offset szFileFilter
            mov    ofn.lpstrFile, offset szFileName
            mov    ofn.nMaxFile, sizeof szFileName
            invoke    GetOpenFileName, addr ofn
            ;如果选择了一个文件,就把它的文件名输出到“文件名”这个 Edit 中:
            test    eax, eax
            .if !zero?
                invoke    SetDlgItemText, hWnd, IDC_EDIT_FILENAME, addr szFileName
            .endif
        .elseif ax == IDC_BUTTON_PROCESS || ax == IDOK
            ;进入加密模块:
            invoke    Protect
        .elseif ax == IDC_BUTTON_ABOUT
            ;“关于”对话框:
            invoke DialogBoxParam, hInstance, DLG_HELP, hWnd, offset AboutProc, 0
        .elseif ax == IDC_BUTTON_EXIT
            ; Over,走人...
            invoke    SendMessage, hWnd, WM_CLOSE, 0, 0
        .endif

    .else
        mov eax, FALSE
        ret
    .endif

    xor    eax, eax
    ret
WndProc endp

;*********************************************************
;“关于”对话框
;*********************************************************
AboutProc    proc uses edx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .if uMsg == WM_CLOSE
        invoke EndDialog, hWnd, 0

    .elseif    uMsg == WM_INITDIALOG
        ;设置我的图标:
        invoke LoadIcon, hInstance, IDI_LC
        invoke SendMessage, hWnd, WM_SETICON, ICON_SMALL, eax

    .elseif uMsg == WM_COMMAND
        mov eax, wParam
        mov edx, eax
        shr edx, 16
        movzx eax, ax
        .if edx == BN_CLICKED
            .if eax == IDCANCEL || eax == IDOK
                invoke EndDialog, hWnd, NULL
            .elseif eax == IDC_BUTTON_HOMEPAGE
                ;打开我的主页:
                invoke ShellExecute, hWnd, CTEXT("open"), CTEXT("http://www.), NULL, NULL, SW_SHOWNORMAL
            .elseif eax == IDC_BUTTON_HELP
                ;打开 help.chm :
                invoke ShellExecute, hWnd, CTEXT("open"), CTEXT("help.chm"), NULL, NULL, SW_SHOWNORMAL
            .endif
        .endif

    .else
        mov eax, FALSE
        ret
    .endif

    mov eax, TRUE
    ret
AboutProc    endp

;*********************************************************
;写入加密节的模块
;*********************************************************
Protect proc    uses ebx ecx edx esi edi
    LOCAL bOK: BOOL

    mov bOK, TRUE

    ;挂接 SEH 处理链,不用多说了吧,呵呵:
    assume    fs:nothing
    push    offset ErrorHandler
    push    fs:[0]
    mov        [SEH], esp
    mov        [SEH+4], ebp
    mov        [SEH+8], ebx
    mov        [SEH+12], esi
    mov        [SEH+16], edi
    mov        [SEH+20], offset @@safe
    mov        fs:[0], esp

    ;获得文件名和密码:
    invoke    GetDlgItemText, [mbp.hwndOwner], IDC_EDIT_FILENAME, addr szFileName, sizeof szFileName
    invoke    GetDlgItemText, [mbp.hwndOwner], IDC_EDIT_PASSWORD, addr szPassword, sizeof szPassword
    invoke    GetDlgItemText, [mbp.hwndOwner], IDC_EDIT_PASSWORD_2, addr szPassword_2, sizeof szPassword_2

    ;打开文件:
    invoke CreateFile, addr szFileName, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL

    ;如果打开文件失败,进行处理:
    .if eax == INVALID_HANDLE_VALUE
        invoke MessageBox, mbp.hwndOwner, CTEXT("打开文件失败!"), addr szCaption, MB_OK or MB_ICONHAND
        invoke GetDlgItem, mbp.hwndOwner, IDC_EDIT_FILENAME
        invoke SetFocus, eax
        invoke SendMessage, eax, EM_SETSEL, 0, -1
        mov bOK, FALSE
        jmp _Err_CreateFile_Exit
    .endif

    ;复制文件句柄:
    mov hFile, eax

    ;取得密码的长度:
    invoke lstrlen, addr szPassword

    ;如果密码长度为0,进行处理:
    .if eax == 0
        invoke MessageBox, mbp.hwndOwner, CTEXT("请先输入密码!"), addr szCaption, MB_OK or MB_ICONHAND
        invoke GetDlgItem, mbp.hwndOwner, IDC_EDIT_PASSWORD
        invoke SetFocus, eax
        mov bOK, FALSE
        jmp @@safe
    .endif

    ;比较两次输入的密码是否相同,如不同,进行处理:
    invoke lstrcmp, addr szPassword, addr szPassword_2
    .if eax != 0
        invoke MessageBox, mbp.hwndOwner, CTEXT("两次输入的密码不符,请检查您的输入!"), addr szCaption, MB_OK or MB_ICONHAND
        mov bOK, FALSE
        jmp @@safe
    .endif

    ;判断“保留备份文件”是否被选中,如果选中了,则备份原文件,备份文件名是在原文件名的最后加“.bak”:
    invoke IsDlgButtonChecked, mbp.hwndOwner, IDC_CHECKBOX_KEEPBACKUP
    .if eax == BST_CHECKED
        invoke lstrcpy, addr szFileNameBak, addr szFileName
        invoke lstrcat, addr szFileNameBak, CTEXT(".bak")
        invoke CopyFile, addr szFileName, addr szFileNameBak, FALSE
    .endif

    ;读入 PE 文件的 IMAGE_DOS_HEADER :
    invoke    ReadFile, hFile, addr img_dos_hdr, sizeof img_dos_hdr, esp, 0

    ;判断是否为一个有效的 PE 文件,呵呵,这个不用多解释了吧?
    cmp    [img_dos_hdr.e_magic], "ZM"
    .if !zero?
        invoke MessageBox, [mbp.hwndOwner], CTEXT("这不是一个有效的 PE 文件!"), addr szCaption, MB_OK or MB_ICONHAND
        mov bOK, FALSE
        jmp @@safe
    .endif

    ;把文件指针指向 IMAGE_NT_HEADERS,并读入该部分内容:
    invoke    SetFilePointer, hFile, img_dos_hdr.e_lfanew, 0, FILE_BEGIN
    invoke    ReadFile, hFile, addr img_nt_hdrs, sizeof img_nt_hdrs, esp, 0

    ;同样,判断是否为一个有效的 PE 文件,呵呵,这个不用多解释了吧?
    cmp    [img_nt_hdrs.Signature], "EP"
    .if !zero?
        invoke MessageBox, [mbp.hwndOwner], CTEXT("这不是一个有效的 PE 文件!"), addr szCaption, MB_OK or MB_ICONHAND
        mov bOK, FALSE
        jmp @@safe
    .endif

    ;储存一些数据,后面会用到:
    xor        eax, eax
    xor        edx, edx
    movzx    ecx, [img_nt_hdrs.FileHeader.NumberOfSections]

@@s000:
    push    ecx
    push    eax
    push    edx

    ;读入 IMAGE_SECTION_HEADER 内容:
    invoke    ReadFile, hFile, addr img_sect_hdr, sizeof img_sect_hdr, esp, 0

    ;判断是否已被加密过:
    invoke lstrcmp, CTEXT(".LC"), addr [img_sect_hdr.Name1]
    .if eax == 0
        invoke MessageBox, [mbp.hwndOwner], CTEXT("您忘记了?文件已被加密过啦……"), addr szCaption, MB_OK or MB_ICONHAND
        mov bOK, FALSE
        jmp @@safe
    .endif

    ;查找可以插入新节的位置:
    pop    edx
    mov    eax, img_sect_hdr.PointerToRawData
    add    eax, img_sect_hdr.SizeOfRawData
    cmp    eax, edx
    jbe    @@s001
    mov    edx, eax
@@s001:
    pop    eax
    mov    ecx, [img_sect_hdr.VirtualAddress]
    add    ecx, [img_sect_hdr.Misc.VirtualSize]
    cmp    eax, ecx
    jae    @@s002
    mov    eax, ecx
@@s002:
    pop    ecx
    loopd    @@s000

    ;新节的名称为“.LC”,呵呵:
    mov    dword ptr [img_sect_hdr.Name1+00h], "CL."
    ;填充剩下的字段:
    mov    [img_sect_hdr.Misc.VirtualSize], attach_size
    mov    [img_sect_hdr.VirtualAddress], eax
    mov    [img_sect_hdr.SizeOfRawData], attach_size
    mov    [img_sect_hdr.PointerToRawData], edx
    mov    [img_sect_hdr.PointerToRelocations], ecx
    mov    [img_sect_hdr.PointerToLinenumbers], ecx
    mov    dword ptr [img_sect_hdr.NumberOfRelocations], ecx

    ;计算新节的加载RVA:
    mov    edx, 00000FFFh
    test [img_sect_hdr.VirtualAddress], edx
    .if !zero?
        and    edx, [img_sect_hdr.VirtualAddress]
        sub    edx, 1000h
        neg    edx
        add    [img_sect_hdr.VirtualAddress], edx
    .endif

    ;计算新节的 PointerToRawData 的偏移值:
    ;(经过试验,200h是在 Win2k/XP 中能被正确加载的比较保险的值)
    xor    edx, edx
    mov    eax, [img_sect_hdr.PointerToRawData]
    mov    ecx, 200h
    div    ecx
    test edx, edx
    .if !zero?
        sub    edx, 200h
        neg    edx
        add    [img_sect_hdr.PointerToRawData], edx
    .endif

    ;设置新节的属性:
    ;code/data/execute/read/write/inited data/un-inited data:(一股脑都加上了,呵呵,这样可以避免出错)
    mov    [img_sect_hdr.Characteristics], 0E00000E0h

    ;把新节信息(IMAGE_SECTION_HEADER)写入文件:
    invoke    WriteFile, [hFile], addr img_sect_hdr, sizeof img_sect_hdr, esp, 0

    ;定位到新节的起始偏移地址:
    invoke    SetFilePointer, [hFile], [img_sect_hdr.PointerToRawData], 0, FILE_BEGIN

    ;把一些有用的信息压栈,后面会用到:
    push esi
    push edi
    mov    esi, attach_start
    mov    edi, offset bNew
    mov    ecx, attach_size shr 2
    rep    movsd
    mov    ecx, attach_size and 3
    rep    movsb
    mov    esi, offset bNew
    mov    ecx, attach_size

    ;改写原程序的代码段的第一条指令的入口地址:
@@copy:
    mov    eax, [esi]
    and    eax, NOT 00000FFFh
    cmp    eax, attach_data_start
    .if zero?
        mov    eax, [esi]
        sub    eax, attach_start
        add    eax, [img_nt_hdrs.OptionalHeader.ImageBase]
        add    eax, [img_sect_hdr.VirtualAddress]
        mov    [esi], eax
    .endif
    inc    esi
    loopd @@copy
    mov    eax, [img_nt_hdrs.OptionalHeader.AddressOfEntryPoint]
    add    eax, [img_nt_hdrs.OptionalHeader.ImageBase]
    mov    dword ptr [bNew + @@oep], eax

    ;初始化crc32table:
    invoke init_crc32table_m

    ;下面赋值给寄存器ebx,以便进行crc32转换:
    ;EBX是待转换的字符串的首地址:
    lea ebx, szPassword

    ;进行crc32转换:
    invoke arraycrc32_m

    ;转换后的密码存放在 [esi] 中:
    mov dword ptr [esi], eax

    ;把转换后的密码加入到新节里面:
    mov    edi, offset bNew + (offset _szRealPassword - attach_start)
    mov ecx, 4
    rep    movsd
    pop    edi
    pop    esi

    ;真正把整个新节的内容写入原程序:
    invoke    WriteFile, [hFile], addr bNew, attach_size, esp, 0
    invoke    SetFilePointer, [hFile], [img_dos_hdr.e_lfanew], 0, FILE_BEGIN
    mov    eax, [img_sect_hdr.VirtualAddress]
    add    eax, attach_code_start - attach_start
    inc    [img_nt_hdrs.FileHeader.NumberOfSections]
    mov    [img_nt_hdrs.OptionalHeader.AddressOfEntryPoint], eax
    add    [img_nt_hdrs.OptionalHeader.SizeOfImage], attach_size
    ;下面两句非常重要,否则加密后的程序在 Win2k 以上的系统中运行会有错误:(感谢vBin兄的指点!)
    push 0
    pop [img_nt_hdrs.OptionalHeader.DataDirectory(88).VirtualAddress]
    invoke    WriteFile, [hFile], addr img_nt_hdrs, sizeof img_nt_hdrs, esp, 0

    ;安全的文件关闭点:
@@safe:
    invoke CloseHandle, [hFile]

    ;如果一开始的打开文件出错,就会来到这里:
_Err_CreateFile_Exit:
    ;如果操作全部完成并没有错误发生,就显示成功提示:
    .if bOK == TRUE
        invoke    MessageBox, [mbp.hwndOwner], CTEXT("加密成功完成!请记住您的密码!"), addr szCaption, MB_OK or MB_ICONINFORMATION
    .endif

    ;取消 SEH 链表:
    pop    fs:[0]
    add    esp, 4

    ;结束啦!哈
    ret
Protect endp

;*********************************************************
; SEH 处理模块
;*********************************************************
ErrorHandler proc C lpExcept:DWORD, lpFrame:DWORD, lpContext:DWORD, lpDispatch:DWORD
    ;这个模块很简单,不多说了,就是在捕捉到 SEH 异常的时候,把当前的出错地址和寄存器信息显示出来:
    mov    eax, [lpExcept]
    mov    ecx, [lpContext]
    invoke    wsprintf, addr szMessage, addr szErrorThread, [eax][EXCEPTION_RECORD.ExceptionAddress], [ecx][CONTEXT.regEax], [ecx][CONTEXT.regEbx], [ecx][CONTEXT.regEcx], [ecx][CONTEXT.regEdx], [ecx][CONTEXT.regEsp], [ecx][CONTEXT.regEbp], [ecx][CONTEXT.regEsi], [ecx][CONTEXT.regEdi]
    invoke MessageBox, [mbp.hwndOwner], addr szMessage, addr szError, MB_OK OR MB_ICONHAND OR MB_APPLMODAL

    ;重要的 SEH 链表内容,自己找一些 SEH 资料来看吧,不多说了:
    mov    eax, [lpContext]
    m2m    [eax][CONTEXT.regEsp], [SEH]
    m2m    [eax][CONTEXT.regEbp], [SEH+4]
    m2m    [eax][CONTEXT.regEbx], [SEH+8]
    m2m    [eax][CONTEXT.regEsi], [SEH+12]
    m2m    [eax][CONTEXT.regEdi], [SEH+16]
    m2m    [eax][CONTEXT.regEip], [SEH+20]

    ; Continue Execution:
    xor    eax, eax
    ret
ErrorHandler endp

;*********************************************************
;异常处理模块
;*********************************************************
ExceptionFilter proc lpExcept:DWORD
    mov    eax, [lpExcept]
    invoke wsprintf, addr szMessage, addr szErrorFinal, [eax][EXCEPTION_RECORD.ExceptionAddress]
    invoke MessageBox, [mbp.hwndOwner], addr szMessage, addr szError, MB_OK OR MB_ICONHAND OR MB_APPLMODAL
    invoke EndDialog, [mbp.hwndOwner], eax
    invoke ExitProcess, 0
    xor    eax, eax
    inc    eax    ; EXCEPTION_EXECUTE_HANDLER
    ret
ExceptionFilter endp

;**********************************************************
;函数功能:生成CRC-32表
;**********************************************************
init_crc32table_m    proc

        ;如果用C语言来表示,应该如下:
        ;
        ;    for (i = 0; i < 256; i++)
        ;    {
        ;        crc = i;
        ;        for (j = 0; j < 8; j++)
        ;        {
        ;            if (crc & 1)
        ;                crc = (crc >> 1) ^ 0xEDB88320;
        ;            else
        ;                crc >>= 1;
        ;        }
        ;        crc32tbl[i] = crc;
        ;    }
        ;
        ;呵呵,让我们把上面的语句改成assembly的:

        mov     ecx, 256        ; repeat for every DWORD in table
        mov     edx, 0EDB88320h
$BigLoop_m:
        lea     eax, [ecx-1]
        push    ecx
        mov     ecx, 8
$SmallLoop_m:
        shr     eax, 1
        jnc     @F
        xor     eax, edx
@@:
        dec        ecx
        jne        $SmallLoop_m
        pop     ecx
        mov     [crc32tble+ecx*4-4], eax
        dec        ecx
        jne        $BigLoop_m

        ret
init_crc32table_m      endp

;**************************************************************
;函数功能:计算CRC-32
;**************************************************************
arraycrc32_m    proc

        ;计算 CRC-32 ,我采用的是把整个字符串当作一个数组,然后把这个数组的首地址赋值给 EBX,把数组的长度赋值给 ECX,然后循环计算,返回值(计算出来的 CRC-32 值)储存在 EAX 中:
        ;
        ; 参数:
        ;       EBX = address of first byte
        ; 返回值:
        ;       EAX = CRC-32 of the entire array
        ;       EBX = ?
        ;       ECX = 0
        ;       EDX = ?

        mov     eax, -1 ; 先初始化eax
        or      ebx, ebx
        jz      $Done_m ; 避免出现空指针
@@:
        mov     dl, [ebx]
        or        dl, dl
        je        $Done_m    ;判断是否对字符串扫描完毕
        
         ;这里我用查表法来计算 CRC-32 ,因此非常快速:
        ;因为这是assembly代码,所以不需要给这个过程传递参数,只需要把oldcrc赋值给EAX,以及把byte赋值给DL:
        ;
        ; 在C语言中的形式:
        ;
        ;   temp = (oldcrc ^ abyte) & 0x000000FF;
        ;   crc  = (( oldcrc >> 8) & 0x00FFFFFF) ^ crc32tbl[temp];
        ;
        ; 参数:
        ;       EAX = old CRC-32
        ;        DL = a byte
        ; 返回值:
        ;       EAX = new CRC-32
        ;       EDX = ?
               
        xor     dl, al
        movzx   edx, dl
        shr     eax, 8
        xor     eax, [crc32tble+edx*4]
        
        inc     ebx        
        jmp        @B

$Done_m:
        not     eax
        ret
arraycrc32_m      endp

;收工!

end main
;********************    over    ********************
;by LC and Comrade


[ 本帖最后由 u332744 于 2012-8-21 09:28 编辑 ]
搜索更多相关主题的帖子: 主程序 源代码 
2012-08-21 09:26
u332744
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-11
收藏
得分:0 
;*********************************************************
;程序名称:LC Crypto
;          本文件是加密部分的源代码
;          本程序综合运用了SEH、PE、CRC32知识
;作者:罗聪
;日期:2002-11-29
;整理:2003-3-2
;出处:http://www.(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“老罗的缤纷天地”(http://www.
;>> 在此特别强烈感激 俄罗斯 的 Comrade 大虾,
;>> 跟他的交流使我受益匪浅,他的源代码更使我汗颜!
;*********************************************************


;*********************************************************
;很有用的宏
;*********************************************************
_call MACRO procedure, parameters:VARARG
    LOCAL param, reversed
    reversed TEXTEQU <>
%    for    param, <parameters>
        reversed CATSTR <param>, <!,>, reversed
    endm
%    for    param, <reversed>
        push    param
    endm
    call    procedure
ENDM

;*********************************************************
;子程序定义
;*********************************************************
Attachment                    proto
AttachWindowProc            proto    :DWORD,:DWORD,:DWORD,:DWORD
init_crc32table                proto
arraycrc32                    proto

;*********************************************************
;常量定义
;*********************************************************
.const
hWndAttachExStyle            equ        0
hWndAttachStyle                equ        WS_MINIMIZEBOX or WS_SYSMENU or WS_CAPTION or WS_OVERLAPPED or WS_THICKFRAME
dwWndAttachWidth            equ        320
dwWndAttachHeight            equ        120
IDC_BUTTON_OK                equ        101
IDM_ATTACH_MENU_ABOUT        equ        102

;*********************************************************
;代码段开始
;*********************************************************
.code
    ;下面是要用到的一大堆变量定义:
    ;以“_”开头,并以 API 函数名相接的,是用来储存通过 GetProcAddress 得到的 API 线形地址:
    attach_start            equ        $
    attach_data_start        equ        $
    hLibUser32                dd        ?
    hLibGDI32                dd        ?
    crc32tbl                dd        256 dup(?)    ;CRC-32 table
    _GetProcAddress            dd        0
    _LoadLibrary            dd        0
    _FreeLibrary            dd        0
    _ExitProcess            dd        0
    _GetModuleHandle        dd        0
    _GetMessage                dd        0
    _TranslateMessage        dd        0
    _DispatchMessage        dd        0
    _GetSystemMetrics        dd        0
    _PostMessage            dd        0
    _SendMessage            dd        0
    _ShowWindow                dd        0
    _UpdateWindow            dd        0
    _LoadCursor                dd        0
    _PostQuitMessage        dd        0
    _MessageBox                dd        0
    _RegisterClassEx        dd        0
    _CreateWindowEx            dd        0
    _DefWindowProc            dd        0
    _SetFocus                dd        0
    _GetWindowLong            dd        0
    _SetWindowLong            dd        0
    _GetDlgItemText            dd        0
    _GetSystemMenu            dd        0
    _AppendMenu                dd        0
    _CreateFontIndirect        dd        0
    _DeleteObject            dd        0
    _IsDialogMessage        dd        0
    _GetDlgItem                dd        0
    _hWndAttach                HWND    0
    _wsprintfA                dd        0
    _SetWindowTextA            dd        0

    szLibUser32                db        "user32", 0
    szLibGDI32                db        "gdi32", 0

    szProcLoadLibrary        db        "LoadLibraryA", 0
    szProcFreeLibrary        db        "FreeLibrary", 0
    szProcExitProcess        db        "ExitProcess", 0
    szProcGetModuleHandle    db        "GetModuleHandleA", 0

    szProcGetMessage        db        "GetMessageA", 0
    szProcTranslateMessage    db        "TranslateMessage", 0
    szProcDispatchMessage    db        "DispatchMessageA", 0
    szProcGetSystemMetrics    db        "GetSystemMetrics", 0
    szProcPostMessage        db        "PostMessageA", 0
    szProcSendMessage        db        "SendMessageA", 0
    szProcShowWindow        db        "ShowWindow", 0
    szProcUpdateWindow        db        "UpdateWindow", 0
    szProcLoadCursor        db        "LoadCursorA", 0
    szProcPostQuitMessage    db        "PostQuitMessage", 0
    szProcMessageBox        db        "MessageBoxA", 0
    szProcRegisterClassEx    db        "RegisterClassExA", 0
    szProcCreateWindowEx    db        "CreateWindowExA", 0
    szProcDefWindowProc        db        "DefWindowProcA", 0
    szProcSetFocus            db        "SetFocus", 0
    szProcGetWindowLong        db        "GetWindowLongA", 0
    szProcSetWindowLong        db        "SetWindowLongA", 0
    szProcGetDlgItemText    db        "GetDlgItemTextA", 0
    szProcGetSystemMenu        db        "GetSystemMenu", 0
    szProcAppendMenu        db        "AppendMenuA", 0
    szIsDialogMessage        db        "IsDialogMessage", 0
    szGetDlgItem            db        "GetDlgItem", 0
    szwsprintfA                db        "wsprintfA", 0
    szSetWindowTextA        db        "SetWindowTextA", 0

    szProcCreateFontIndirect    db    "CreateFontIndirectA", 0
    szProcDeleteObject        db        "DeleteObject", 0

    _fnt                    LOGFONT    <13, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH or FF_DONTCARE, "宋体">

    _szAppClass                db        "LCCrypto32", 0
    _szAppTitle                db        "LC Crypto :: v0.1 by LC", 0
    _szMenuAbout            db        "&About LC Crypto...", 0
    _szMsgAbout                db        "【 LC Crypto 】", 13, 10
                            db        "Version: 0.1", 13, 10, 13, 10
                            db        "作者:罗聪", 13, 10
                            db        "E-Mail: lcother@, 13, 10, 13, 10
                            db        "老罗的缤纷天地", 13, 10
                            db        "http://www., 0
    _szClassEdit            db        "Edit", 0
    _szClassStatic            db        "Static", 0
    _szClassButton            db        "Button", 0
    _szTitlePassword        db        "请输入密码:", 0
    _szOK                    db        "确定(&O)", 0
    _szWrongPassword        db        "密码不正确,请重新输入!", 0
    _szTemplate                db        "--= 您还剩下 %d 次机会 =--", 0
    _szRealPassword            db        16 dup (?)
    _szPassword                db        16 dup (?)
    _szChanceCount            db        255 dup(?)
    _hFont                    dd        0
    _bCorrect                db        0
    _hWndChanceCount        HWND    0
    _wc                        WNDCLASSEX    <0>
    _msg                    MSG        <0>
    _nCount                    dd        3

;*********************************************************
;真正的代码开始
;*********************************************************
    attach_code_start        equ        $

;*********************************************************
;附加段的子程序处理模块
;*********************************************************
Attachment proc
    ;以下是经典的查找 kernel32.dll 的基地址的代码:
    mov    eax, [esp]
    and    eax, 0FFFF0000h
@@chk:
    cmp    dword ptr [eax], 00905A4Dh    ; 比较一下……
    je    @@fnd                        ; 找到了?
    sub    eax, 1000h                    ; faint,找不到,减少1000h作为跨度
    jmp    @@chk                        ; Go on!
@@fnd:
    ;以下的涉及到 PE 格式的操作不多说了,看不懂的话……我也没办法了
    push ebp
    push ebx
    push esi
    push edi
    mov    ebp, eax
    add    eax, [eax][IMAGE_DOS_HEADER.e_lfanew]
    mov    edi, [eax][IMAGE_NT_HEADERS.OptionalHeader.DataDirectory]
    add    edi, ebp
    mov    esi, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNames]
    add    esi, ebp

    ;在 kernel32.dll 里面查找 GetProcAddress 这个 API 的线形地址:
    xor    edx, edx
@@name:
    mov    eax, [esi]
    add    eax, ebp
@@chgp:    ; GetProcAddress()
    cmp    dword ptr [eax+00h], "PteG"    ; GetP
    jne    @@next
    cmp    dword ptr [eax+04h], "Acor"    ; rocA
    jne    @@next
    cmp    dword ptr [eax+08h], "erdd"    ; ddre
    jne    @@next
    cmp    word ptr [eax+0Ch], "ss"    ; ss
    jne    @@next
    mov    eax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals]
    add    eax, ebp
    movzx ebx, word ptr [edx*2+eax]
    mov    eax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfFunctions]
    add    eax, ebp
    mov    eax, [ebx*4+eax]
    add    eax, ebp
    ;找到了,储存起来:
    mov    [_GetProcAddress], eax
@@next:
    add    esi, 4
    inc    edx
    cmp    edx, [edi][IMAGE_EXPORT_DIRECTORY.NumberOfNames]
    jne    @@name

    ;下面的是通过 GetProcAddress 获得一大堆 API 的线形地址,并储存起来,供后面使用:
    _call    [_GetProcAddress], ebp, offset szProcFreeLibrary
    mov        [_FreeLibrary], eax
    _call    [_GetProcAddress], ebp, offset szProcGetModuleHandle
    mov        [_GetModuleHandle], eax
    _call    [_GetProcAddress], ebp, offset szProcExitProcess
    mov        [_ExitProcess], eax
    _call    [_GetProcAddress], ebp, offset szProcLoadLibrary
    mov        [_LoadLibrary], eax
    ;载入 user32.dll ,并储存它的句柄:
    _call    eax, offset szLibUser32
    mov        [hLibUser32], eax
    _call    [_GetProcAddress], eax, offset szProcGetMessage
    mov        [_GetMessage], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcTranslateMessage
    mov        [_TranslateMessage], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcDispatchMessage
    mov        [_DispatchMessage], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcGetSystemMetrics
    mov        [_GetSystemMetrics], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcPostMessage
    mov        [_PostMessage], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcSendMessage
    mov        [_SendMessage], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcShowWindow
    mov        [_ShowWindow], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcUpdateWindow
    mov        [_UpdateWindow], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcLoadCursor
    mov        [_LoadCursor], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcPostQuitMessage
    mov        [_PostQuitMessage], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcMessageBox
    mov        [_MessageBox], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcRegisterClassEx
    mov        [_RegisterClassEx], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcCreateWindowEx
    mov        [_CreateWindowEx], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcDefWindowProc
    mov        [_DefWindowProc], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcSetFocus
    mov        [_SetFocus], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcGetWindowLong
    mov        [_GetWindowLong], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcSetWindowLong
    mov        [_SetWindowLong], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcGetDlgItemText
    mov        [_GetDlgItemText], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcGetSystemMenu
    mov        [_GetSystemMenu], eax
    _call    [_GetProcAddress], [hLibUser32], offset szProcAppendMenu
    mov        [_AppendMenu], eax
    _call    [_GetProcAddress], [hLibUser32], offset szIsDialogMessage
    mov        [_IsDialogMessage], eax
    _call    [_GetProcAddress], [hLibUser32], offset szGetDlgItem
    mov        [_GetDlgItem], eax
    _call    [_GetProcAddress], [hLibUser32], offset szwsprintfA
    mov        [_wsprintfA], eax
    _call    [_GetProcAddress], [hLibUser32], offset szSetWindowTextA
    mov        [_SetWindowTextA], eax

    ;载入 gdi32.dll ,并储存它的句柄:
    _call    [_LoadLibrary], offset szLibGDI32
    mov        [hLibGDI32], eax

    ;通过 GetProcAddress 获得 gdi32.dll 里面的两个 API 的线形地址,并储存起来:
    _call    [_GetProcAddress], eax, offset szProcCreateFontIndirect
    mov        [_CreateFontIndirect], eax
    _call    [_GetProcAddress], [hLibGDI32], offset szProcDeleteObject
    mov        [_DeleteObject], eax

    pop        edi
    pop        esi
    pop        ebx
    pop        ebp

    ;熟悉 Win32 编程的朋友对下面的代码一定非常熟悉,一看就明白,不多说了:
    _call    [_GetModuleHandle], 0
    mov        [_wc.hInstance], eax
    or        [_wc.cbSize], sizeof _wc
    or        [_wc.style], CS_HREDRAW or CS_VREDRAW
    or        [_wc.lpfnWndProc], offset AttachWindowProc
    or        [_wc.hbrBackground], COLOR_BTNFACE+1
    or        [_wc.lpszClassName], offset _szAppClass
    _call    [_LoadCursor], 0, IDC_ARROW
    mov        [_wc.hCursor], eax
    _call    [_RegisterClassEx], offset _wc
    _call    [_GetSystemMetrics], SM_CYSCREEN
    sar        eax, 1
    sub        eax, dwWndAttachHeight shr 1
    push    eax
    _call    [_GetSystemMetrics], SM_CXSCREEN
    sar        eax, 1
    sub        eax, dwWndAttachWidth shr 1
    pop        ecx
    _call    [_CreateWindowEx], hWndAttachExStyle, offset _szAppClass, offset _szAppTitle, hWndAttachStyle, eax, ecx, dwWndAttachWidth, dwWndAttachHeight, 0, 0, [_wc.hInstance], 0
    mov        [_hWndAttach], eax
    push    eax
    _call    [_ShowWindow], eax, SW_SHOW
    _call    [_UpdateWindow]

    ;处理消息循环的地方:
@@ml00:
    xor        eax, eax
    _call    [_GetMessage], offset _msg, eax, eax, eax
    test    eax, eax
    jz        @@ml01
    mov        eax, offset _msg
    push    eax
    _call    [_IsDialogMessage], [_hWndAttach], eax
    .if eax == FALSE
        mov        eax, offset _msg
        push    eax
        _call    [_TranslateMessage], eax
        _call    [_DispatchMessage]
    .endif
    jmp        @@ml00
@@ml01:
    _call    [_FreeLibrary], [hLibGDI32]
    _call    [_FreeLibrary], [hLibUser32]
    .if [_bCorrect]
        @@oep    equ    $ - attach_start + 1
        mov    eax, 00000000h
        jmp    eax
    .endif
    _call    [_ExitProcess], 0
Attachment endp


;*********************************************************
;附加段的消息循环
;*********************************************************
AttachWindowProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
    .if [uMsg] == WM_CREATE
        ;在系统菜单中加入我的“关于”对话框:
        _call    [_GetSystemMenu], [hWnd], 0
        push    offset _szMenuAbout
        push    IDM_ATTACH_MENU_ABOUT
        push    MFT_STRING
        push    eax
        _call    [_AppendMenu], eax, MFT_SEPARATOR, 0, 0
        _call    [_AppendMenu]

        ;创建字体:
        _call    [_CreateFontIndirect], offset _fnt
        mov        [_hFont], eax

        ;初始化还可输入密码的次数:
        push    ebp
        mov        ebp, esp
        sub        esp, 12
        _call    [_wsprintfA], offset _szChanceCount, offset _szTemplate, _nCount
        add        esp, 12
        mov        esp, ebp
        pop        ebp

        ;创建 Static 控件,显示还可输入多少次密码:
        _call    [_CreateWindowEx], 0, offset _szClassStatic, offset _szChanceCount, SS_CENTER or SS_CENTERIMAGE or WS_VISIBLE or WS_CHILD, 10, 32, 300, 22, [hWnd], 0, [_wc.hInstance], 0
        mov        [_hWndChanceCount], eax
        ;设置 Static 的字体:
        _call    [_SendMessage], eax, WM_SETFONT, [_hFont], 0

        ;创建 Static 控件,显示“请输入密码:”字样:
        _call    [_CreateWindowEx], 0, offset _szClassStatic, offset _szTitlePassword, SS_RIGHT or SS_CENTERIMAGE or WS_VISIBLE or WS_CHILD, 10, 10, 80, 22, [hWnd], 0, [_wc.hInstance], 0
        _call    [_SendMessage], eax, WM_SETFONT, [_hFont], 0

        ;创建 Edit 控件,供用户输入密码:
        _call    [_CreateWindowEx], WS_EX_STATICEDGE, offset _szClassEdit, 0, ES_AUTOHSCROLL or ES_PASSWORD or WS_VISIBLE or WS_TABSTOP or WS_CHILD, 95, 12, 205, 15, [hWnd], 0, [_wc.hInstance], 0
        push    eax    ; SetFocus()

        push    0    ; SendMessage()
        push    sizeof _szPassword
        push    EM_SETLIMITTEXT    ;限制可输入的最大的密码位数
        push    eax

        push    IDC_EDIT_PASSWORD    ; SetWindowLong()
        push    GWL_ID
        push    eax
        _call    [_SendMessage], eax, WM_SETFONT, [_hFont], 0
        _call    [_SetWindowLong]
        _call    [_SendMessage]
        _call    [_SetFocus]

        ;创建 Button 控件,也就是“确定”按钮:
        _call    [_CreateWindowEx], 0, offset _szClassButton, offset _szOK, BS_FLAT or BS_DEFPUSHBUTTON or WS_VISIBLE or WS_TABSTOP or WS_CHILD, 120, 60, 80, 20, [hWnd], 0, [_wc.hInstance], 0
        push    IDC_BUTTON_OK    ; SetWindowLong()
        push    GWL_ID
        push    eax
        _call    [_SendMessage], eax, WM_SETFONT, [_hFont], 0
        _call    [_SetWindowLong]

    .elseif [uMsg] == WM_COMMAND
        mov    eax,    [wParam]
        .if ax == IDC_BUTTON_OK || ax == IDOK
            ;把用户输入的密码储存起来:
            mov        edi, offset _szPassword
            mov        ecx, sizeof _szPassword shr 2
            xor        eax, eax
            rep        stosd
            _call    [_GetDlgItemText], [hWnd], IDC_EDIT_PASSWORD, offset _szPassword, sizeof _szPassword

            ;初始化crc32table:
            invoke    init_crc32table

            ;下面赋值给寄存器ebx,以便进行crc32转换:
            ;EBX是待转换的字符串的首地址:
            lea        ebx, _szPassword

            ;进行crc32转换:
            invoke    arraycrc32

            ;把经过 CRC32 转换的密码与正确的密码进行比较:
            cmp dword ptr [_szRealPassword], eax
            sete    [_bCorrect]

            ;如果还可输入密码的次数已经用完了,就关闭程序:
            .if zero? || _nCount == 1
                _call    [_PostMessage], [hWnd], WM_CLOSE, 0, 0
            .else
                ;否则如果密码错误的话,给出“错误密码”提示:
                _call    [_MessageBox], [hWnd], offset _szWrongPassword, offset _szAppTitle, MB_OK or MB_ICONASTERISK or MB_APPLMODAL
                _call    [_GetDlgItem], [hWnd], IDC_EDIT_PASSWORD

                ;设置 Edit 为当前焦点:
                _call    [_SetFocus], eax

                ;全选密码框里面的字符串:
                _call    [_SendMessage], eax, EM_SETSEL, 0, -1

                ;减少一次还可输入密码的次数:
                dec        _nCount

                ;把还可输入密码的次数显示在 Static 控件里面:
                push    ebp
                mov        ebp, esp
                sub        esp, 12
                _call    [_wsprintfA], offset _szChanceCount, offset _szTemplate, _nCount
                add        esp, 12
                mov        esp, ebp
                pop        ebp
                _call    [_SetWindowTextA], [_hWndChanceCount], offset _szChanceCount
            .endif
        .endif

    .elseif [uMsg] == WM_SYSCOMMAND && [wParam] == IDM_ATTACH_MENU_ABOUT
        ;显示“关于”这个 MessageBox :
        _call    [_MessageBox], [hWnd], offset _szMsgAbout, offset _szAppTitle, MB_OK or MB_ICONASTERISK or MB_APPLMODAL

    .elseif [uMsg] == WM_CLOSE
        ;关闭前,要释放 hFont ,以免造成内存泄漏:
        _call    [_DeleteObject], [_hFont]

    .elseif [uMsg]==WM_DESTROY
        ;关闭程序:
        _call    [_PostQuitMessage], 0

        xor    eax, eax
        ret
    .endif

    pop    ebp
    jmp    [_DefWindowProc]
AttachWindowProc endp

;**********************************************************
;函数功能:生成CRC-32表
;**********************************************************
init_crc32table    proc

        ;如果用C语言来表示,应该如下:
        ;
        ;    for (i = 0; i < 256; i++)
        ;    {
        ;        crc = i;
        ;        for (j = 0; j < 8; j++)
        ;        {
        ;            if (crc & 1)
        ;                crc = (crc >> 1) ^ 0xEDB88320;
        ;            else
        ;                crc >>= 1;
        ;        }
        ;        crc32tbl[i] = crc;
        ;    }
        ;
        ;呵呵,让我们把上面的语句改成assembly的:

        mov     ecx, 256        ; repeat for every DWORD in table
        mov     edx, 0EDB88320h
$BigLoop:
        lea     eax, [ecx-1]
        push    ecx
        mov     ecx, 8
$SmallLoop:
        shr     eax, 1
        jnc     @F
        xor     eax, edx
@@:
        dec        ecx
        jne        $SmallLoop
        pop     ecx
        mov     [crc32tbl+ecx*4-4], eax
        dec        ecx
        jne        $BigLoop

        ret
init_crc32table      endp

;**************************************************************
;函数功能:计算CRC-32
;**************************************************************
arraycrc32    proc

        ;计算 CRC-32 ,我采用的是把整个字符串当作一个数组,然后把这个数组的首地址赋值给 EBX,把数组的长度赋值给 ECX,然后循环计算,返回值(计算出来的 CRC-32 值)储存在 EAX 中:
        ;
        ; 参数:
        ;       EBX = address of first byte
        ; 返回值:
        ;       EAX = CRC-32 of the entire array
        ;       EBX = ?
        ;       ECX = 0
        ;       EDX = ?

        mov     eax, -1 ; 先初始化eax
        or      ebx, ebx
        jz      $Done   ; 避免出现空指针
@@:
        mov     dl, [ebx]
        or        dl, dl
        je        $Done    ;判断是否对字符串扫描完毕
        
         ;这里我用查表法来计算 CRC-32 ,因此非常快速:
        ;因为这是assembly代码,所以不需要给这个过程传递参数,只需要把oldcrc赋值给EAX,以及把byte赋值给DL:
        ;
        ; 在C语言中的形式:
        ;
        ;   temp = (oldcrc ^ abyte) & 0x000000FF;
        ;   crc  = (( oldcrc >> 8) & 0x00FFFFFF) ^ crc32tbl[temp];
        ;
        ; 参数:
        ;       EAX = old CRC-32
        ;        DL = a byte
        ; 返回值:
        ;       EAX = new CRC-32
        ;       EDX = ?
               
        xor     dl, al
        movzx   edx, dl
        shr     eax, 8
        xor     eax, [crc32tbl+edx*4]
        
        inc     ebx        
        jmp        @B

$Done:
        not     eax
        ret
arraycrc32      endp

;收工!

attach_size    equ    $ - offset attach_start
;********************    over    ********************
;by LC and Comrade


[ 本帖最后由 u332744 于 2012-8-21 09:28 编辑 ]
2012-08-21 09:26
u332744
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-11
收藏
得分:0 
上面两段ASM程序,加上下面这段rc文件:
#include "resource.h"

#define IDC_STATIC                -1
#define IDI_LC                    1
#define IDC_BUTTON_BROWSE        3000
#define IDC_EDIT_FILENAME        3001
#define IDC_EDIT_PASSWORD        3002
#define    IDC_EDIT_PASSWORD_2        3010
#define    IDC_CHECKBOX_KEEPBACKUP    3003
#define IDC_BUTTON_PROCESS        3004
#define IDC_BUTTON_ABOUT        3005
#define IDC_BUTTON_EXIT            3006
#define    IDC_BUTTON_HELP            3007
#define    IDC_BUTTON_HOMEPAGE        3008
#define DLG_HELP                3009

IDI_LC    ICON    "lc.ico"
1 24 DISCARDABLE "XpTheme.xml"    //实现 XP Style

LC_DIALOG DIALOGEX 10, 10, 195, 120
STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "LC Crypto :: v0.1"
FONT 9, "宋体", 0, 0, 0x0
BEGIN
    GROUPBOX        "操作", IDC_STATIC, 5, 5, 185, 80
    LTEXT            "文 件 名:", IDC_STATIC, 10, 20, 40, 10
    EDITTEXT        IDC_EDIT_FILENAME, 50, 18, 115, 10, ES_AUTOHSCROLL// | NOT WS_BORDER, WS_EX_STATICEDGE
    PUSHBUTTON        "..", IDC_BUTTON_BROWSE, 170, 18, 15, 10, BS_FLAT | BS_RIGHT | BS_BOTTOM
    LTEXT            "密    码:", IDC_STATIC, 10, 35, 40, 10
    EDITTEXT        IDC_EDIT_PASSWORD, 50, 33, 115, 10, ES_PASSWORD | ES_AUTOHSCROLL// | NOT WS_BORDER, WS_EX_STATICEDGE
    LTEXT            "重复密码:", IDC_STATIC, 10, 50, 40, 10
    EDITTEXT        IDC_EDIT_PASSWORD_2, 50, 48, 115, 10, ES_PASSWORD | ES_AUTOHSCROLL// | NOT WS_BORDER, WS_EX_STATICEDGE
    AUTOCHECKBOX    "(&B)保留备份文件.Bak (强烈建议!!!)", IDC_CHECKBOX_KEEPBACKUP, 15, 65, 170, 12
    PUSHBUTTON        "关于(&A)", IDC_BUTTON_ABOUT, 13, 95, 50, 15, BS_FLAT | BS_CENTER
    PUSHBUTTON        "加密(&P)", IDC_BUTTON_PROCESS, 73, 95, 50, 15, BS_FLAT | BS_CENTER
    PUSHBUTTON        "退出(&X)", IDC_BUTTON_EXIT, 133, 95, 50, 15, BS_FLAT | BS_CENTER
END

DLG_HELP DIALOG DISCARDABLE 10, 10, 220, 110
STYLE DS_SETFONT | DS_CENTER | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "关于 LC Crypto"
FONT 9, "宋体"
BEGIN
    ICON            IDI_LC, IDC_STATIC, 10, 15, 20, 20
    LTEXT           "【 LC Crypto 】    v0.1 测试版", IDC_STATIC, 40, 5, 170, 15
    LTEXT            "100% 纯 Win32ASM 编写,用于 PE 可执行文件的加密。", IDC_STATIC, 40, 20, 170, 15
    LTEXT            "希望您能喜欢。 ^_^", IDC_STATIC, 40, 40, 170, 15
    CONTROL            "", IDC_STATIC, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 10, 55, 200, 10
    LTEXT            "Writer: 罗聪", IDC_STATIC, 10, 60, 150, 15
    LTEXT            "E-Mail: lcother@, IDC_STATIC, 10, 70, 150, 15
    LTEXT            "hOMEPAGe: http://www., IDC_STATIC, 10, 80, 150, 15
    DEFPUSHBUTTON    "确  定(&O)", IDOK, 160, 75, 50, 15, BS_FLAT | BS_CENTER
    PUSHBUTTON        "详细帮助(&H)", IDC_BUTTON_HELP, 160, 60, 50, 15, BS_FLAT | BS_CENTER
    PUSHBUTTON        "主  页(&P)", IDC_BUTTON_HOMEPAGE, 160, 90, 50, 15, BS_FLAT | BS_CENTER
    CONTROL            "", IDC_STATIC, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 10, 90, 150, 10
    LTEXT            "老罗作品 保留所有版权 2002-11-29", IDC_STATIC, 10, 95, 150, 15
END


[ 本帖最后由 u332744 于 2012-8-21 09:35 编辑 ]
2012-08-21 09:30
u332744
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-11
收藏
得分:0 
makefile:

EXE = LCCrypto.exe        #&Ouml;&cedil;&para;¨&Ecirc;&auml;&sup3;&ouml;&Icirc;&Auml;&frac14;&thorn;
OBJS = LCCrypto.obj        #&ETH;è&Ograve;&ordf;&micro;&Auml;&Auml;&iquest;±ê&Icirc;&Auml;&frac14;&thorn;
RES = LCCrypto.res        #&ETH;è&Ograve;&ordf;&micro;&Auml;×&Ecirc;&Ocirc;&acute;&Icirc;&Auml;&frac14;&thorn;

LINK_FLAG = /subsystem:windows    #&Aacute;&not;&frac12;&Oacute;&Ntilde;&iexcl;&Iuml;&icirc;
ML_FLAG = /c /coff        #±à&Ograve;&euml;&Ntilde;&iexcl;&Iuml;&icirc;

$(EXE): $(OBJS) $(RES)
    Link $(LINK_FLAG) $(OBJS) $(RES)

.asm.obj:
    ml $(ML_FLAG) $<
.rc.res:
    rc $<

clean:
    del *.obj
    del *.res
2012-08-21 09:36
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:18 
360报的罢 很正常 操作PE文件了
2012-08-21 12:11
u332744
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-11
收藏
得分:0 
回复 5楼 zklhp
那该怎么办? 不是360,赛门铁克,家里微软自带的也报错.
2012-08-21 15:36
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
以下是引用u332744在2012-8-21 15:36:55的发言:

那该怎么办? 不是360,赛门铁克,家里微软自带的也报错.

那没办法了 这段代码确实有猫腻 不能算误报
2012-08-21 16:04
u332744
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-11
收藏
得分:0 
这个汇编代码只是操作自己本身的EXE的PE格式吧? 难道还操作其他系统文件不成?
2012-08-21 17:05
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
以下是引用u332744在2012-8-21 17:05:36的发言:

这个汇编代码只是操作自己本身的EXE的PE格式吧? 难道还操作其他系统文件不成?

那就不知道了 反正已经被杀了 而且不算误报
2012-08-21 17:08
u332744
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-11
收藏
得分:0 
你知道是哪段代码引发的被杀吗?
真的是死的不明不白啊
2012-08-21 17:23
快速回复:为什么会报病毒,是个加密程序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.033757 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved