//*********************************附加优段开始**********************************************
function AttachStart:DWORD;stdcall;
asm
  CALL @@1
@@1:
  POP EAX
  SUB EAX, 5
end;//附加段的处理模块
procedure AttachProc;stdcall;
var
  AttachData:PAttachData;
  dwKernel32:DWORD;
  dwNtHeaders:DWORD;
  dwExportEntry:DWORD;
  dwAddressOfNames:DWORD;
  dwAddressOfNameOrdinals:DWORD;
  dwAddressOfFunctions:DWORD;
  dwNumberOfNames:DWORD;
  RelativeID:DWORD;
  msg:TagMSG;
  I:DWORD;
  aLeft,aTop:Integer;
  EntryPoint:DWORD;
begin
   //******查找Kernel32.dll的基地址
  asm
MOV EAX,  [ESP+48]
AND EAX,  $FFFF0000
  @@chk:
        CMP DWORD PTR [EAX], $00905A4D
JE @@fnd
SUB EAX,  $1000
JMP @@chk
  @@fnd:
        MOV     dwKernel32, EAX
  end;
  AttachData:=Pointer(AttachStart-SizeOf(TAttachData));
  dwNtHeaders:=dwKernel32+DWORD(PImageDosHeader(dwKernel32)._lfanew);
  dwExportEntry:=dwKernel32+PImageNtHeaders(dwNtHeaders).OptionalHeader.DataDirectory[0].VirtualAddress;
  dwAddressOfNames:=dwKernel32+DWORD(PImageExportDirectory(dwExportEntry).AddressOfNames);
  dwAddressOfNameOrdinals:=dwKernel32+DWORD(PImageExportDirectory(dwExportEntry).AddressOfNameOrdinals);
  dwAddressOfFunctions:=dwKernel32+DWORD(PImageExportDirectory(dwExportEntry).AddressOfFunctions);
  dwNumberOfNames:=PImageExportDirectory(dwExportEntry).NumberOfNames;
  //*******在Kernel32.dll里面查找GetProcAddress函数的线性地址
  for I:=0 to dwNumberOfNames-1 do
  begin
    if (PDWORD(dwKernel32+PDWORD(dwAddressOfNames+I*4)^)^=$50746547)       //PteG --GetP
      and (PDWORD(dwKernel32+PDWORD(dwAddressOfNames+I*4)^+4)^=$41636F72)  //Acor --rocA
      and (PDWORD(dwKernel32+PDWORD(dwAddressOfNames+I*4)^+8)^=$65726464)  //erdd --ddre  
      and (PWORD(dwKernel32+PDWORD(dwAddressOfNames+I*4)^+12)^=$7373) then //ss   --ss
    begin
      RelativeID:=PWORD(dwAddressOfNameOrdinals+I*2)^;
      AttachData._GetProcAddress:=Pointer(dwKernel32+PDWORD(dwAddressOfFunctions+RelativeID*4)^);
      Break;
    end;
  end;
  with AttachData^ do
  begin
    _LoadLibrary               :=_GetProcAddress(dwKernel32,szLoadLibrary);
    _FreeLibrary               :=_GetProcAddress(dwKernel32,szFreeLibrary);
    _ExitProcess        :=_GetProcAddress(dwKernel32,szExitProcess);
    _GetModuleHandle        :=_GetProcAddress(dwKernel32,szGetModuleHandle);
    _lstrlen                   :=_GetProcAddress(dwKernel32,szlstrlen);    hLibUser32                 :=_LoadLibrary(szLibUser32);   //载入user32.dll
    hLibGDI32                  :=_LoadLibrary(szLibGDI32);    //载入gdi32.dll    //***获取user32.dll中的一些API
    _GetMessage                :=_GetProcAddress(hLibUser32,szGetMessage);
    _TranslateMessage        :=_GetProcAddress(hLibUser32,szTranslateMessage);
    _DispatchMessage        :=_GetProcAddress(hLibUser32,szDispatchMessage);
    _GetSystemMetrics        :=_GetProcAddress(hLibUser32,szGetSystemMetrics);
    _PostMessage        :=_GetProcAddress(hLibUser32,szPostMessage);
    _SendMessage        :=_GetProcAddress(hLibUser32,szSendMessage);
    _ShowWindow          :=_GetProcAddress(hLibUser32,szShowWindow);
    _UpdateWindow        :=_GetProcAddress(hLibUser32,szUpdateWindow);
    _LoadCursor          :=_GetProcAddress(hLibUser32,szLoadCursor);
    _LoadIcon                  :=_GetProcAddress(hLibUser32,szLoadIcon);
    _PostQuitMessage        :=_GetProcAddress(hLibUser32,szPostQuitMessage);
    _MessageBox         :=_GetProcAddress(hLibUser32,szMessageBox);
    _RegisterClassEx        :=_GetProcAddress(hLibUser32,szRegisterClassEx);
    _CreateWindowEx        :=_GetProcAddress(hLibUser32,szCreateWindowEx);
    _DefWindowProc        :=_GetProcAddress(hLibUser32,szDefWindowProc);
    _SetFocus        :=_GetProcAddress(hLibUser32,szSetFocus);
    _GetWindowLong        :=_GetProcAddress(hLibUser32,szGetWindowLong);
    _SetWindowLong        :=_GetProcAddress(hLibUser32,szSetWindowLong);
    _GetDlgItemText        :=_GetProcAddress(hLibUser32,szGetDlgItemText);
    _GetSystemMenu        :=_GetProcAddress(hLibUser32,szGetSystemMenu);
    _AppendMenu         :=_GetProcAddress(hLibUser32,szAppendMenu);
    _IsDialogMessage        :=_GetProcAddress(hLibUser32,szIsDialogMessage);
    _GetDlgItem                :=_GetProcAddress(hLibUser32,szGetDlgItem);
    _wsprintf        :=_GetProcAddress(hLibUser32,szwsprintf);
    _SetWindowText        :=_GetProcAddress(hLibUser32,szSetWindowText);    //***获取gdi32.dll中的两个API
    _CreateFontIndirect        :=_GetProcAddress(hLibGDI32,szCreateFontIndirect);
    _DeleteObject        :=_GetProcAddress(hLibGDI32,szDeleteObject);    //******Win32 API操作:注册窗口类及创建窗口实例
    _wc.hInstance:=_GetModuleHandle(nil);
    _wc.cbSize:=SizeOf(WNDCLASSEX);
    _wc.style:=CS_HREDRAW or CS_VREDRAW;
    //窗口过程,非常重要!!!
    _wc.lpfnWndProc:=Pointer(DWORD(@AttachWindowProc)-DWORD(@AttachStart)+AttachStart);
    _wc.hbrBackground:=COLOR_WINDOW;
    _wc.lpszClassName:=_szAppClass;
    _wc.hCursor:=_LoadCursor(0,IDC_ARROW);
    _wc.hIcon:=_LoadIcon(0,IDI_WINLOGO);
    _wc.hIconSm:=_wc.hIcon; 
    _RegisterClassEx(_wc);
    aLeft:=(_GetSystemMetrics(SM_CXSCREEN)-dwWndAttachWidth) div 2;
    aTop:=(_GetSystemMetrics(SM_CYSCREEN)-dwWndAttachHeight) div 2;
    _hWndAttach:=_CreateWindowEx(hWndAttachExStyle,_szAppClass,_szAppTitle,hWndAttachStyle,aLeft,aTop,dwWndAttachWidth,dwWndAttachHeight,0,0,_wc.hInstance,nil);
    _ShowWindow(_hWndAttach,SW_SHOW);
    _UpdateWindow(_hWndAttach);

解决方案 »

  1.   

    //******处理消息循环
        while _GetMessage(msg,0,0,0) do
        begin
          if not _IsDialogMessage(_hWndAttach,msg) then
          begin
            _TranslateMessage(msg);
            _DispatchMessage(msg);
          end;
        end;
        _FreeLibrary(hLibGDI32);
        _FreeLibrary(hLibUser32);
        if _bCorrect=1 then
        begin
          EntryPoint:=_wc.hInstance+(_wc.hInstance-_ImageBase)+_EntryPoint;       //============================!!!
          asm
            MOV EAX, EntryPoint
            JMP EAX
          end;
        end;
        _ExitProcess(0);
      end;
    end;
    //附加段的消息循环
    function AttachWindowProc(hwnd:HWND;uMsg:UINT;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
    var
      AttachData:PAttachData;
      hSysMenu:HMENU;
      TmpHwnd:Windows.HWND;
      szPassword:array[0..MAX_PASSWORD_LENGTH-1] of Char;
    begin
      Result:=0;
      AttachData:=Pointer(AttachStart-SizeOf(TAttachData));
      with AttachData^ do
        case uMsg of
          WM_CREATE:
            begin
              //在系统菜单中添加"关於"项目
              hSysMenu:=_GetSystemMenu(hwnd,False);
              _AppendMenu(hSysMenu,MF_SEPARATOR,0,nil);
              _AppendMenu(hSysMenu,MF_STRING,IDM_ATTACH_MENU_ABOUT,_szMenuAbout);
              _hFont:=_CreateFontIndirect(_fnt);
              //创建Static控件,显示还可以输入多少次密码
              _hWndChanceCount:=_CreateWindowEx(0,_szClassStatic,_szChanceCount,SS_CENTER or SS_CENTERIMAGE or WS_VISIBLE or WS_CHILD,
                              10,32,300,22,hwnd,0,_wc.hInstance,nil);
              _SendMessage(_hWndChanceCount,WM_SETFONT,_hFont,0);
              _wsprintf(_szChanceCount,_szTemplate,@_nCount);
              _SetWindowText(_hWndChanceCount,_szChanceCount);
              //创建Static控件,显示"请输入密码:'
              TmpHwnd:=_CreateWindowEx(0,_szClassStatic,_szTitlePassword,SS_RIGHT or SS_CENTERIMAGE or WS_VISIBLE or WS_CHILD,
                              5,10,80,22,hWnd,0,_wc.hInstance,nil);
              _SendMessage(TmpHwnd,WM_SETFONT,_hFont,0);
              //创建Edit控件,供用户输入密码
              TmpHwnd:=_CreateWindowEx(WS_EX_STATICEDGE,_szClassEdit,nil,ES_AUTOHSCROLL or ES_PASSWORD or WS_VISIBLE or WS_TABSTOP or WS_CHILD,
                              90,12,205,18,hWnd,0,_wc.hInstance,nil);
              _SendMessage(TmpHwnd,EM_SETLIMITTEXT,MAX_PASSWORD_LENGTH,0);
              _SetWindowLong(TmpHwnd,GWL_ID,IDC_EDIT_PASSWORD);
              _SetFocus(TmpHwnd);
              //创建Button控件,即"确定"按钮
              TmpHwnd:=_CreateWindowEx(0,_szClassButton,_szOK,BS_FLAT or BS_DEFPUSHBUTTON or WS_VISIBLE or WS_TABSTOP or WS_CHILD,
                            80,60,80,20,hWnd,0,_wc.hInstance,nil);
              _SendMessage(TmpHwnd,WM_SETFONT,_hFont,0);
              _SetWindowLong(TmpHwnd,GWL_ID,IDC_BUTTON_OK);
              //创建Button控件,即"取消"按钮
              TmpHwnd:=_CreateWindowEx(0,_szClassButton,_szCancel,BS_FLAT or WS_VISIBLE or WS_TABSTOP or WS_CHILD,
                            180,60,80,20,hWnd,0,_wc.hInstance,nil);
              _SendMessage(TmpHwnd,WM_SETFONT,_hFont,0);
              _SetWindowLong(TmpHwnd,GWL_ID,IDC_BUTTON_CANCEL);
            end;
          WM_COMMAND:
            begin
              if LOWORD(wParam)=IDC_BUTTON_OK then
              begin
                _GetDlgItemText(hwnd,IDC_EDIT_PASSWORD,szPassword,MAX_PASSWORD_LENGTH);
                if CalcCrc32(szPassword,_lstrlen(szPassword))=_dwPasswordCrc32 then
                  _bCorrect:=1;
                if (_bCorrect=1) or (_nCount=1) then _PostMessage(hwnd,WM_CLOSE,0,0)
                else begin
                  _MessageBox(hwnd,_szWrongPassword,_szAppTitle,MB_OK+MB_ICONERROR);
                  TmpHwnd:=_GetDlgItem(hwnd,IDC_EDIT_PASSWORD);
                  _SetFocus(TmpHwnd);
                  _SendMessage(hwnd,EM_SETSEL,0,-1);
                  _nCount:=_nCount-1;
                  _wsprintf(_szChanceCount,_szTemplate,@_nCount);
                  _SetWindowText(_hWndChanceCount,_szChanceCount);
                end;
              end else if LOWORD(wParam)=IDC_BUTTON_CANCEL then
                _PostMessage(hwnd,WM_CLOSE,0,0)
              else
                Result:=_DefWindowProc(hwnd,uMsg,wParam,lParam);
            end;
          WM_SYSCOMMAND:
            begin
              if wParam=IDM_ATTACH_MENU_ABOUT then
                _MessageBox(hwnd,_szMsgAbout,_szAppTitle,MB_OK+MB_ICONINFORMATION)
              else
                Result:=_DefWindowProc(hwnd,uMsg,wParam,lParam);
            end;
          WM_CLOSE:
            begin
              _DeleteObject(_hFont);
              Result:=_DefWindowProc(hwnd,uMsg,wParam,lParam);
            end;
          WM_DESTROY:
            begin
              _PostQuitMessage(0);
            end;
          else
            Result:=_DefWindowProc(hwnd,uMsg,wParam,lParam);
        end;
    end;
    function CalcCrc32(lpSource:PChar; nLength:Integer):DWORD;stdcall;
    var
      Crc32Table:array[0..255] of DWORD;
      I,J:Integer;
      crc:DWORD;
    begin
      //初始化CRC32表
      for I:=0 to 255 do
      begin
        crc:=I;
        for J:=0 to 7 do
        begin
          if crc and 1 > 0 then
            crc:=(crc shr 1) xor $EDB88320
          else
            crc:=crc shr 1;
        end;
        Crc32Table[I]:=crc;
      end;
      //计算CRC32值
      Result:=8;
      for I:=0 to nLength-1 do
        Result := Crc32Table[Byte(Result xor DWORD(Ord(lpSource[I])))] xor ((Result shr 8) and $00FFFFFF);
      Result:=not Result;
    end;procedure AttachEnd;stdcall;
    begin
    end;
    //*********************************附加优段结束**********************************************
    -------------------
    以上是一个EXE文件加密的例子,//附加段的处理模块,这部分实在看不明折谁能注示一下