Subversion Repositories Kolibri OS

Rev

Rev 4421 | Rev 5559 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 5039 $
  9.  
  10. include 'export.inc'
  11.  
  12. align 4
  13.  
  14. proc load_PE stdcall, file_name:dword
  15.            locals
  16.              image  dd ?
  17.              entry  dd ?
  18.              base   dd ?
  19.            endl
  20.  
  21.         stdcall load_file, [file_name]
  22.         test    eax, eax
  23.         jz      .fail
  24.  
  25.         mov     [image], eax
  26.  
  27.         mov     edx, [eax+STRIPPED_PE_HEADER.SizeOfImage]
  28. ;        mov     cl, [eax+STRIPPED_PE_HEADER.Subsystem]
  29.         cmp     word [eax], STRIPPED_PE_SIGNATURE
  30.         jz      @f
  31.  
  32.         mov     edx, [eax+60]
  33. ;        mov     cl, [eax+5Ch+edx]
  34.         mov     edx, [eax+80+edx]
  35.  
  36. @@:
  37.         mov     [entry], 0
  38. ;        cmp     cl, 1
  39. ;        jnz     .cleanup
  40.         stdcall kernel_alloc, edx
  41.         test    eax, eax
  42.         jz      .cleanup
  43.  
  44.         mov     [base], eax
  45.  
  46.         push    ebx ebp
  47.         mov     ebx, [image]
  48.         mov     ebp, eax
  49.         call    map_PE
  50.         pop     ebp ebx
  51.  
  52.         mov     [entry], eax
  53.         test    eax, eax
  54.         jnz     .cleanup
  55.  
  56.         stdcall kernel_free, [base]
  57. .cleanup:
  58.         stdcall kernel_free, [image]
  59.         mov     eax, [entry]
  60.         ret
  61. .fail:
  62.         xor     eax, eax
  63.         ret
  64. endp
  65.  
  66. map_PE:                    ;ebp=base:dword, ebx=image:dword
  67.         push    edi
  68.         push    esi
  69.         sub     esp, .locals_size
  70. virtual at esp
  71. .numsections    dd      ?
  72. .import_names   dd      ?
  73. .import_targets dd      ?
  74. .peheader       dd      ?
  75. .bad_import     dd      ?
  76. .import_idx     dd      ?
  77. .import_descr   dd      ?
  78. .relocs_rva     dd      ?
  79. .relocs_size    dd      ?
  80. .section_header_size dd ?
  81. .AddressOfEntryPoint    dd ?
  82. .ImageBase      dd      ?
  83. .locals_size = $ - esp
  84. end virtual
  85.         cmp     word [ebx], STRIPPED_PE_SIGNATURE
  86.         jz      .stripped
  87.  
  88.         mov     edx, ebx
  89.         add     edx, [ebx+60]
  90.         movzx   eax, word [edx+6]
  91.         mov     [.numsections], eax
  92.         mov     eax, [edx+40]
  93.         mov     [.AddressOfEntryPoint], eax
  94.         mov     eax, [edx+52]
  95.         mov     [.ImageBase], eax
  96.         mov     ecx, [edx+84]
  97.         mov     [.section_header_size], 40
  98.         mov     eax, [edx+128]
  99.         mov     [.import_descr], eax
  100.         mov     eax, [edx+160]
  101.         mov     [.relocs_rva], eax
  102.         mov     eax, [edx+164]
  103.         mov     [.relocs_size], eax
  104.         add     edx, 256
  105.  
  106.         jmp     .common
  107. .stripped:
  108.         mov     eax, [ebx+STRIPPED_PE_HEADER.AddressOfEntryPoint]
  109.         mov     [.AddressOfEntryPoint], eax
  110.         mov     eax, [ebx+STRIPPED_PE_HEADER.ImageBase]
  111.         mov     [.ImageBase], eax
  112.         movzx   eax, [ebx+STRIPPED_PE_HEADER.NumberOfSections]
  113.         mov     [.numsections], eax
  114.         movzx   ecx, [ebx+STRIPPED_PE_HEADER.NumberOfRvaAndSizes]
  115.         xor     eax, eax
  116.         mov     [.relocs_rva], eax
  117.         mov     [.relocs_size], eax
  118.         test    ecx, ecx
  119.         jz      @f
  120.         mov     eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_IMPORT*8]
  121. @@:
  122.         mov     [.import_descr], eax
  123.         cmp     ecx, SPE_DIRECTORY_BASERELOC
  124.         jbe     @f
  125.         mov     eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8]
  126.         mov     [.relocs_rva], eax
  127.         mov     eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8+4]
  128.         mov     [.relocs_size], eax
  129. @@:
  130.         mov     [.section_header_size], 28
  131.         lea     edx, [ebx+ecx*8+sizeof.STRIPPED_PE_HEADER+8]
  132.         mov     ecx, [ebx+STRIPPED_PE_HEADER.SizeOfHeaders]
  133.  
  134. .common:
  135.         mov     esi, ebx
  136.         mov     edi, ebp
  137.         shr     ecx, 2
  138.         rep movsd
  139.  
  140.         cmp     [.numsections], 0
  141.         jz      .nosections
  142. .copy_sections:
  143.         mov     eax, [edx+8]
  144.         test    eax, eax
  145.         je      .no_section_data
  146.         mov     esi, ebx
  147.         mov     edi, ebp
  148.         add     esi, [edx+12]
  149.         mov     ecx, eax
  150.         add     edi, [edx+4]
  151.  
  152.         add     ecx, 3
  153.         shr     ecx, 2
  154.         rep movsd
  155.  
  156. .no_section_data:
  157.         mov     ecx, [edx]
  158.         cmp     ecx, eax
  159.         jbe     .no_section_fill
  160.         sub     ecx, eax
  161.         add     eax, [edx+4]
  162.         lea     edi, [eax+ebp]
  163.  
  164.         xor     eax, eax
  165.         rep stosb
  166.  
  167. .no_section_fill:
  168.         add     edx, [.section_header_size]
  169.         dec     [.numsections]
  170.         jnz     .copy_sections
  171. .nosections:
  172.         cmp     [.relocs_size], 0
  173.         je      .no_relocations
  174.         mov     esi, ebp
  175.         mov     ecx, ebp
  176.         sub     esi, [.ImageBase]
  177.         add     ecx, [.relocs_rva]
  178. .relocs_block:
  179.         mov     edi, [ecx]
  180.         add     edi, ebp
  181.         mov     ebx, [ecx+4]
  182.         add     ecx, 8
  183.         sub     [.relocs_size], ebx
  184.         sub     ebx, 8
  185.         shr     ebx, 1
  186.         jz      .relocs_next_block
  187. .one_reloc:
  188.         movzx   eax, word [ecx]
  189.         add     ecx, 2
  190.         mov     edx, eax
  191.         shr     eax, 12
  192.         and     edx, 4095
  193.         cmp     eax, 3
  194.         jne     @f
  195.         add     [edx+edi], esi
  196. @@:
  197.         dec     ebx
  198.         jnz     .one_reloc
  199. .relocs_next_block:
  200.         cmp     [.relocs_size], 0
  201.         jg      .relocs_block
  202. .no_relocations:
  203.         cmp     [.import_descr], 0
  204.         je      .no_imports
  205.         add     [.import_descr], ebp
  206.         mov     [.bad_import], 0
  207. .import_block:
  208.         mov     ecx, [.import_descr]
  209.         cmp     dword [ecx+4], 0
  210.         jne     @f
  211.         cmp     dword [ecx+12], 0
  212.         je      .done_imports
  213. @@:
  214.         mov     edx, dword [ecx]
  215.         mov     ecx, dword [ecx+16]
  216.         test    edx, edx
  217.         jnz     @f
  218.         mov     edx, ecx
  219. @@:
  220.         mov     [.import_idx], 0
  221.         add     ecx, ebp
  222.         add     edx, ebp
  223.         mov     [.import_names], edx
  224.         mov     [.import_targets], ecx
  225. .import_func:
  226.         mov     esi, [.import_idx]
  227.         mov     edi, [.import_names]
  228.         mov     eax, [edi+esi*4]
  229.         test    eax, eax
  230.         je      .next_import_block
  231.         js      .next_import_block
  232.         lea     edi, [ebp+eax]
  233.         mov     eax, [.import_targets]
  234.         mov     dword [eax+esi*4], 0
  235.         lea     esi, [edi+2]
  236.         movzx   ebx, word [edi]
  237.         push    32
  238.         mov     ecx, [__exports+32]
  239.         mov     eax, [ecx+OS_BASE+ebx*4]
  240.         add     eax, OS_BASE
  241.         push    eax
  242.         push    esi
  243.         call    strncmp
  244.         test    eax, eax
  245.         jz      .import_func_found
  246.         xor     ebx, ebx
  247. .import_func_candidate:
  248.         push    32
  249.         mov     ecx, [__exports+32]
  250.         mov     eax, [ecx+OS_BASE+ebx*4]
  251.         add     eax, OS_BASE
  252.         push    eax
  253.         push    esi
  254.         call    strncmp
  255.         test    eax, eax
  256.         je      .import_func_found
  257.         inc     ebx
  258.         cmp     ebx, [__exports+24]
  259.         jb      .import_func_candidate
  260.  
  261.         mov     esi, msg_unresolved
  262.         call    sys_msg_board_str
  263.         lea     esi, [edi+2]
  264.         call    sys_msg_board_str
  265.         mov     esi, msg_CR
  266.         call    sys_msg_board_str
  267.  
  268.         mov     [.bad_import], 1
  269.         jmp     .next_import_func
  270. .import_func_found:
  271.         mov     esi, [__exports+28]
  272.         mov     edx, [.import_idx]
  273.         mov     ecx, [.import_targets]
  274.         mov     eax, [esi+OS_BASE+ebx*4]
  275.         add     eax, OS_BASE
  276.         mov     [ecx+edx*4], eax
  277. .next_import_func:
  278.         inc     [.import_idx]
  279.         jmp     .import_func
  280. .next_import_block:
  281.         add     [.import_descr], 20
  282.         jmp     .import_block
  283. .done_imports:
  284.         xor     eax, eax
  285.         cmp     [.bad_import], 0
  286.         jne     @f
  287. .no_imports:
  288.         mov     eax, ebp
  289.         add     eax, [.AddressOfEntryPoint]
  290. @@:
  291.         add     esp, .locals_size
  292.         pop     esi
  293.         pop     edi
  294.         ret
  295.