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