0,0 → 1,1117 |
|
HEAP_BASE equ 0x01000000 |
;HEAP_SIZE equ 0x01000000 |
|
struc MEM_BLOCK |
{ .next_block dd ? |
.prev_block dd ? ;+4 |
.list_next dd ? ;+8 |
.list_prev dd ? ;+12 |
.base dd ? ;+16 |
.size dd ? ;+20 |
.flags dd ? ;+24 |
.handle dd ? ;+28 |
} |
|
FREE_BLOCK equ 4 |
USED_BLOCK equ 8 |
|
virtual at 0 |
MEM_BLOCK MEM_BLOCK |
end virtual |
|
MEM_BLOCK_SIZE equ 8*4 |
|
block_next equ MEM_BLOCK.next_block |
block_prev equ MEM_BLOCK.prev_block |
list_next equ MEM_BLOCK.list_next |
list_prev equ MEM_BLOCK.list_prev |
block_base equ MEM_BLOCK.base |
block_size equ MEM_BLOCK.size |
block_flags equ MEM_BLOCK.flags |
|
macro calc_index op |
{ shr op, 12 |
dec op |
cmp op, 63 |
jna @f |
mov op, 63 |
@@: |
} |
|
macro remove_from_list op |
{ mov edx, [op+list_next] |
mov ecx, [op+list_prev] |
test edx, edx |
jz @f |
mov [edx+list_prev], ecx |
@@: |
test ecx, ecx |
jz @f |
mov [ecx+list_next], edx |
@@: |
mov [op+list_next],0 |
mov [op+list_prev],0 |
} |
|
macro remove_from_free op |
{ |
remove_from_list op |
|
mov eax, [op+block_size] |
calc_index eax |
cmp [mem_block_list+eax*4], op |
jne @f |
mov [mem_block_list+eax*4], edx |
@@: |
cmp [mem_block_list+eax*4], 0 |
jne @f |
btr [mem_block_mask], eax |
@@: |
} |
|
macro remove_from_used op |
{ |
remove_from_list op |
cmp [mem_used_list], op |
jne @f |
mov [mem_used_list], edx |
@@: |
} |
|
align 4 |
proc init_kernel_heap |
|
mov ecx, 64/4 |
mov edi, mem_block_list |
xor eax, eax |
cld |
rep stosd |
|
mov ecx, 512/4 |
mov edi, mem_block_map |
not eax |
rep stosd |
|
mov [mem_block_start], mem_block_map |
mov [mem_block_end], mem_block_map+512 |
mov [mem_block_arr], HEAP_BASE |
|
stdcall alloc_pages, dword 32 |
mov ecx, 32 |
mov edx, eax |
mov edi, HEAP_BASE |
|
.l1: |
stdcall map_page,edi,edx,PG_SW |
add edi, 0x1000 |
add edx, 0x1000 |
dec ecx |
jnz .l1 |
|
mov edi, HEAP_BASE |
mov ebx, edi |
add ebx, MEM_BLOCK_SIZE |
xor eax, eax |
mov [edi+block_next], ebx |
mov [edi+block_prev], eax |
mov [edi+list_next], eax |
mov [edi+list_prev], eax |
mov [edi+block_base], HEAP_BASE |
mov [edi+block_size], 4096*MEM_BLOCK_SIZE |
mov [edi+block_flags], USED_BLOCK |
|
mov [ebx+block_next], eax |
mov [ebx+block_prev], eax |
mov [ebx+list_next], eax |
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE |
|
mov ecx, [MEM_AMOUNT] |
sub ecx, 0x00C00000 + 4096*MEM_BLOCK_SIZE |
mov [ebx+block_size], ecx |
mov [ebx+block_flags], FREE_BLOCK |
|
mov [mem_block_mask], eax |
mov [mem_block_mask+4],0x80000000 |
|
mov [mem_used_list], eax |
mov [mem_block_list+63*4], ebx |
mov byte [mem_block_map], 0xFC |
ret |
endp |
|
align 4 |
proc get_block stdcall, index:dword |
|
mov eax, 63 |
mov ecx, [index] |
cmp ecx, eax |
jna @f |
;cmova ecx, eax |
mov ecx, eax |
@@: |
xor esi, esi |
xor ebx, ebx |
xor edx, edx |
not edx |
|
cmp ecx, 32 |
jb .bit_test |
|
sub ecx, 32 |
add ebx, 32 |
add esi, 4 |
|
.bit_test: |
shl edx, cl |
and edx, [mem_block_mask+esi] |
jz .high_mask |
bsf eax, edx |
add ebx, eax |
mov eax, [mem_block_list+ebx*4] |
ret |
|
.high_mask: |
|
add esi, 4 |
add ebx, 32 |
test esi, 0xFFFFFFF8 |
jnz .big_error |
mov edx, [mem_block_mask+esi] |
and edx, edx |
jz .high_mask |
bsf eax, edx |
add ebx, eax |
mov eax, [mem_block_list+ebx*4] |
ret |
|
.big_error: |
xor eax, eax |
ret |
endp |
|
|
align 4 |
proc alloc_mem_block |
|
pushfd |
cli |
mov ebx, [mem_block_start] |
mov ecx, [mem_block_end] |
.l1: |
bsf eax,[ebx]; |
jnz found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
popfd |
xor eax,eax |
ret |
|
found: |
btr [ebx], eax |
mov [mem_block_start],ebx |
sub ebx, mem_block_map |
shl ebx, 3 |
add eax,ebx |
shl eax, 5 |
add eax, [mem_block_arr] |
popfd |
ret |
endp |
|
proc free_mem_block |
pushfd |
cli |
sub eax, [mem_block_arr] |
shr eax, 5 |
|
mov ebx, mem_block_map |
bts [ebx], eax |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [mem_block_start], eax |
ja @f |
popfd |
ret |
@@: |
mov [mem_block_start], eax |
popfd |
ret |
.err: |
xor eax, eax |
popfd |
ret |
endp |
|
align 4 |
proc alloc_kernel_space stdcall, size:dword |
local block_ind:DWORD |
|
pushfd |
cli |
|
mov eax, [size] |
add eax, 0xFFF |
and eax, 0xFFFFF000; |
mov [size], eax |
|
shr eax, 12 |
sub eax, 1 |
|
mov [block_ind], eax |
|
stdcall get_block, eax |
and eax, eax |
jz .error |
|
mov edi, eax ;edi - pBlock |
|
cmp [edi+block_flags], FREE_BLOCK |
jne .error |
|
mov [block_ind], ebx ;index of allocated block |
|
mov eax, [edi+block_size] |
cmp eax, [size] |
je .m_eq_size |
|
call alloc_mem_block |
and eax, eax |
jz .error |
|
mov esi, eax ;esi - splitted block |
|
mov [esi+block_next], edi |
mov eax, [edi+block_prev] |
mov [esi+block_prev], eax |
mov [edi+block_prev], esi |
mov [esi+list_next], 0 |
mov [esi+list_prev], 0 |
and eax, eax |
jz @f |
mov [eax+block_next], esi |
@@: |
mov ebx, [edi+block_base] |
mov [esi+block_base], ebx |
mov edx, [size] |
mov [esi+block_size], edx |
add [edi+block_base], edx |
sub [edi+block_size], edx |
|
mov eax, [edi+block_size] |
shr eax, 12 |
sub eax, 1 |
cmp eax, 63 |
jna @f |
mov eax, 63 |
@@: |
cmp eax, [block_ind] |
je .m_eq_ind |
|
mov ebx, [edi+list_next] |
test ebx, ebx |
jz @f |
|
mov [ebx+list_prev], edi |
@@: |
mov ecx, [block_ind] |
mov [mem_block_list+ecx*4], ebx |
|
and ebx, ebx |
jnz @f |
btr [mem_block_mask], ecx |
@@: |
mov edx, [mem_block_list+eax*4] |
mov [edi+list_next], edx |
test edx, edx |
jz @f |
mov [edx+list_prev], edi |
@@: |
mov [mem_block_list+eax*4], edi |
bts [mem_block_mask], eax |
.m_eq_ind: |
mov ebx, [mem_used_list] |
mov [esi+list_next], ebx |
test ebx, ebx |
jz @f |
mov [ebx+list_prev], esi |
@@: |
mov [esi+block_flags], USED_BLOCK |
mov [mem_used_list], esi |
mov eax, [esi+block_base] |
popfd |
ret |
|
.m_eq_size: |
remove_from_list edi |
mov [mem_block_list+ecx*4], edx |
and edx, edx |
jnz @f |
mov ecx, [block_ind] |
btr [mem_block_mask], ecx |
@@: |
mov ebx, [mem_used_list] |
mov [edi+list_next], ebx |
test ebx, ebx |
jnz @f |
mov [ebx+list_prev], edi |
@@: |
mov [mem_used_list], edi |
mov [edi+block_flags], USED_BLOCK |
mov eax, [edi+block_base] |
popfd |
ret |
.error: |
xor eax, eax |
popfd |
ret |
endp |
|
align 4 |
proc free_kernel_space stdcall, base:dword |
|
mov eax, [base] |
mov esi, [mem_used_list] |
@@: |
test esi, esi |
jz .fail |
|
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_next] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
|
mov edi, [esi+block_next] |
test edi, edi |
jz .prev |
|
cmp [edi+block_flags], FREE_BLOCK |
jne .prev |
|
remove_from_free edi |
|
mov edx, [edi+block_next] |
mov [esi+block_next], edx |
test edx, edx |
jz @f |
|
mov [edx+block_prev], esi |
@@: |
mov ecx, [edi+block_size] |
add [esi+block_size], ecx |
|
mov eax, edi |
call free_mem_block |
.prev: |
mov edi, [esi+block_prev] |
test edi, edi |
jz .insert |
|
cmp [edi+block_flags], FREE_BLOCK |
jne .insert |
|
remove_from_used esi |
|
mov edx, [esi+block_next] |
mov [edi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], edi |
@@: |
mov eax, esi |
call free_mem_block |
|
mov ecx, [edi+block_size] |
mov eax, [esi+block_size] |
add eax, ecx |
mov [edi+block_size], eax |
|
calc_index eax |
calc_index ecx |
cmp eax, ecx |
je .m_eq |
|
push ecx |
remove_from_list edi |
pop ecx |
|
cmp [mem_block_list+ecx*4], edi |
jne @f |
mov [mem_block_list+ecx*4], edx |
@@: |
cmp [mem_block_list+ecx*4], 0 |
jne @f |
btr [mem_block_mask], ecx |
@@: |
mov esi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], edi |
mov [edi+list_next], esi |
test esi, esi |
jz @f |
mov [esi+list_prev], edi |
@@: |
bts [mem_block_mask], eax |
.m_eq: |
xor eax, eax |
not eax |
ret |
.insert: |
remove_from_used esi |
|
mov eax, [esi+block_size] |
calc_index eax |
|
mov edi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], esi |
mov [esi+list_next], edi |
test edi, edi |
jz @f |
mov [edi+list_prev], esi |
@@: |
bts [mem_block_mask], eax |
mov [esi+block_flags],FREE_BLOCK |
xor eax, eax |
not eax |
ret |
.fail: |
xor eax, eax |
ret |
endp |
|
align 4 |
proc kernel_alloc stdcall, size:dword |
locals |
lin_addr dd ? |
pages_count dd ? |
endl |
|
mov eax, [size] |
add eax, 0xFFF |
and eax, 0xFFFFF000; |
mov [size], eax |
and eax, eax |
jz .error |
mov ebx, eax |
shr ebx, 12 |
mov [pages_count], ebx |
|
stdcall alloc_kernel_space, eax |
and eax, eax |
jz .error |
mov [lin_addr], eax |
|
mov ecx, [pages_count] |
mov edx, eax |
mov ebx, ecx |
|
shr ecx, 3 |
jz .next |
|
and ebx, not 7 |
push ebx |
stdcall alloc_pages, ebx |
pop ecx ; yes ecx!!! |
and eax, eax |
jz .error |
|
mov edi, eax |
mov edx, [lin_addr] |
@@: |
stdcall map_page,edx,edi,dword PG_SW |
add edx, 0x1000 |
add edi, 0x1000 |
dec ecx |
jnz @B |
.next: |
mov ecx, [pages_count] |
and ecx, 7 |
jz .end |
|
@@: push ecx |
call alloc_page |
pop ecx |
test eax, eax |
jz .error |
|
stdcall map_page,edx,eax,dword PG_SW |
add edx, 0x1000 |
dec ecx |
jnz @B |
.end: |
mov eax, [lin_addr] |
ret |
|
.error: |
xor eax, eax |
ret |
endp |
|
align 4 |
proc kernel_free stdcall, base:dword |
locals |
size dd ? |
endl |
|
mov eax, [base] |
mov esi, [mem_used_list] |
@@: |
test esi, esi |
jz .fail |
|
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_next] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
|
mov ecx, [esi+block_size]; |
mov [size], ecx |
|
stdcall free_kernel_space, [base] |
test eax, eax |
jz .fail |
|
mov ecx, [size] |
mov edi, [base] |
|
shr ecx, 12 |
mov esi, edi |
shr edi, 10 |
add edi, pages_tab |
xor edx, edx |
.release: |
mov eax, [edi] |
test eax, 1 |
jz .next |
|
call free_page |
mov [edi],edx |
.next: |
invlpg [esi] |
add esi, 0x1000 |
add edi, 4 |
dec ecx |
jnz .release |
.fail: |
ret |
endp |
|
restore block_next |
restore block_prev |
restore block_list |
restore block_base |
restore block_size |
restore block_flags |
|
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
|
align 4 |
proc init_heap stdcall, heap_size:dword |
locals |
tab_count dd ? |
endl |
|
mov edx, [heap_size] |
and edx, edx |
jz .exit |
add edx, 4095 |
and edx, not 4095 |
mov [heap_size], edx |
add edx, 0x003FFFFF |
and edx, not 0x003FFFFF |
shr edx, 22 |
mov [tab_count], edx |
|
mov ebx,[CURRENT_TASK] |
shl ebx,8 |
mov esi, [PROC_BASE+0x8c+ebx] |
add esi, 0x003FFFFF |
and esi, not 0x003FFFFF |
mov edi, esi |
mov [PROC_BASE+0x18+ebx], esi |
add esi, [heap_size] |
mov [PROC_BASE+0x1C+ebx], esi |
|
mov eax, cr3 |
and eax, not 0xFFF |
stdcall map_page,[current_pdir],eax,dword PG_SW |
|
add edi, new_app_base |
@@: |
call alloc_page |
test eax, eax |
jz .exit |
|
stdcall map_page_table, [current_pdir], edi, eax |
add edi, 0x00400000 |
dec edx |
jnz @B |
|
mov ecx, [tab_count] |
shl ecx, 12-2 |
mov ebx,[CURRENT_TASK] |
shl ebx,8 |
mov edi, [PROC_BASE+0x18+ebx] |
add edi, new_app_base |
shr edi, 10 |
mov esi, edi |
add edi, pages_tab |
xor eax, eax |
cld |
rep stosd |
|
stdcall map_page,[current_pdir],dword PG_UNMAP |
|
mov ebx, [heap_size] |
mov eax, ebx |
sub eax, 4096 |
or ebx, FREE_BLOCK |
mov [pages_tab+esi], ebx |
|
ret |
.exit: |
xor eax, eax |
ret |
endp |
|
align 4 |
proc user_alloc stdcall, alloc_size:dword |
|
mov ecx, [alloc_size] |
add ecx, (4095+4096) |
and ecx, not 4095 |
|
mov ebx, [CURRENT_TASK] |
shl ebx, 8 |
mov esi, dword [ebx+PROC_BASE+0x18]; heap_base |
mov edi, dword [ebx+PROC_BASE+0x1C]; heap_top |
add esi, new_app_base |
add edi, new_app_base |
|
l_0: |
cmp esi, edi |
jae m_exit |
|
mov ebx, esi |
shr ebx, 12 |
mov eax, [pages_tab+ebx*4] |
test eax, FREE_BLOCK |
jz test_used |
and eax, 0xFFFFF000 |
cmp eax, ecx ;alloc_size |
jb m_next |
|
mov edx, esi |
add edx, ecx |
sub eax, ecx; |
or eax, FREE_BLOCK |
shr edx, 12 |
mov [pages_tab+edx*4], eax |
|
or ecx, USED_BLOCK |
mov [pages_tab+ebx*4], ecx |
shr ecx, 12 |
dec ecx |
inc ebx |
@@: |
mov dword [pages_tab+ebx*4], 2 |
inc ebx |
dec ecx |
jnz @B |
|
mov eax, esi |
add eax, 4096 |
sub eax, new_app_base |
ret |
m_next: |
add esi, eax |
jmp l_0 |
test_used: |
test eax, USED_BLOCK |
jz m_exit |
|
and eax, 0xFFFFF000 |
add esi, eax |
jmp l_0 |
m_exit: |
xor eax, eax |
ret |
endp |
|
align 4 |
proc user_free stdcall, base:dword |
|
mov esi, [base] |
test esi, esi |
jz .exit |
|
sub esi, 4096 |
shr esi, 12 |
mov eax, [pages_tab+esi*4] |
test eax, USED_BLOCK |
jz @f |
|
and eax, not 4095 |
mov ecx, eax |
or eax, FREE_BLOCK |
mov [pages_tab+esi*4], eax |
inc esi |
sub ecx, 4096 |
shr ecx, 12 |
.release: |
mov eax, [pages_tab+esi*4] |
call free_page |
inc esi |
dec ecx |
jnz .release |
@@: |
mov ebx, [CURRENT_TASK] |
shl ebx, 8 |
mov esi, dword [ebx+PROC_BASE+0x18]; heap_base |
mov edi, dword [ebx+PROC_BASE+0x1C]; heap_top |
shr esi, 12 |
shr edi, 12 |
@@: |
mov eax, [pages_tab+esi*4] |
test eax, USED_BLOCK |
jz .test_free |
shr eax, 12 |
add esi, eax |
jmp @B |
.test_free: |
test eax, FREE_BLOCK |
jz .err |
mov edx, eax |
shr edx, 12 |
add edx, esi |
cmp edx, edi |
jae .exit |
|
mov ebx, [pages_tab+edx*4] |
test ebx, USED_BLOCK |
jz .next_free |
|
shr ebx, 12 |
add edx, ebx |
mov esi, edx |
jmp @B |
.next_free: |
test ebx, FREE_BLOCK |
jz .err |
and dword [pages_tab+edx*4], 0 |
add eax, ebx |
and eax, not 4095 |
or eax, FREE_BLOCK |
mov [pages_tab+esi*4], eax |
jmp @B |
.exit: |
xor eax, eax |
inc eax |
ret |
.err: |
xor eax, eax |
ret |
endp |
|
|
;proc new_mem_resize stdcall, new_size:dword |
; |
; stdcall wait_mutex, pg_data.pg_mutex |
; |
; mov edi, [new_size] |
; add edi,4095 |
; and edi,not 4095 |
; mov [new_size], edi |
|
; mov edx,[CURRENT_TASK] |
; shl edx,8 |
; mov esi, [PROC_BASE+0x8c+edx] |
; add esi, 4095 |
; and esi, not 4095 |
|
; cmp edi, esi |
; jae .expand |
|
; shr edi, 12 |
; shr esi, 12 |
; |
;@@: mov eax, [pages_tab+0x4000+edi*4] |
; test eax, 1 |
; jz .next |
; mov dword [pages_tab+0x4000+edi*4], 2 |
; mov ebx, edi |
; shl ebx, 12 |
; invlpg [ebx+std_application_base_address] |
; call free_page |
; |
;.next: add edi, 1 |
; cmp edi, esi |
; jb @B |
; |
;.update_size: |
|
; mov ebx, [new_size] |
; mov [PROC_BASE+0x8c+edx],ebx |
; |
;;search threads and update |
;;application memory size infomation |
; mov ecx,[PROC_BASE+0xb8+edx] |
; mov eax,2 |
|
;.search_threads: |
;;eax = current slot |
;;ebx = new memory size |
;;ecx = page directory |
; cmp eax,[TASK_COUNT] |
; jg .search_threads_end |
; mov edx,eax |
; shl edx,5 |
; cmp word [CURRENT_TASK+edx+0xa],9 ;if slot empty? |
; jz .search_threads_next |
; shl edx,3 |
; cmp [PROC_BASE+edx+0xb8],ecx ;if it is our thread? |
; jnz .search_threads_next |
; mov [PROC_BASE+edx+0x8c],ebx ;update memory size |
;.search_threads_next: |
; inc eax |
; jmp .search_threads |
;.search_threads_end: |
; xor eax, eax |
; dec [pg_data.pg_mutex] |
; ret |
; |
; |
;.expand: |
; add edi, new_app_base |
; add esi, new_app_base |
; |
;.grow: call alloc_page |
; test eax, eax |
; jz .exit |
; stdcall map_page,esi,eax,dword PG_UW |
|
; push edi |
; mov edi, esi |
; xor eax, eax |
; mov ecx, 1024 |
; cld |
; rep stosd |
; pop edi |
|
; add esi, 0x1000 |
; cmp esi, edi |
; jna .grow |
; jmp .update_size |
;.exit: |
; xor eax, eax |
; inc eax |
; dec [pg_data.pg_mutex] |
; ret |
;endp |
|
|
align 4 |
proc alloc_dll |
pushf |
cli |
bsf eax, [dll_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: |
btr [dll_map], eax |
popf |
shl eax, 5 |
add eax, dll_tab |
ret |
endp |
|
align 4 |
proc alloc_service |
pushf |
cli |
bsf eax, [srv_map] |
jnz .find |
popf |
xor eax, eax |
ret |
|
.find: btr [srv_map], eax |
popf |
shl eax,5 |
add eax, srv_tab |
ret |
endp |
|
if NEW |
|
align 16 |
new_services: |
cmp eax, 10 |
jb .fail |
ja @f |
|
push dword [ebp+8+new_app_base] |
call get_mem_info |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 11 |
ja @f |
|
push dword [ebp+8+new_app_base] |
call init_heap |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 12 |
ja @f |
|
push dword [ebp+8+new_app_base] |
call user_alloc |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 13 |
ja @f |
|
push dword [ebp+8+new_app_base] |
call user_free |
mov [esp+36], eax |
ret |
|
@@: |
cmp eax, 14 |
ja @f |
mov eax, [ebp+8+new_app_base] |
add eax,new_app_base |
stdcall get_notify, eax |
ret |
;@@: |
; cmp eax, 15 |
; ja @f |
; call set_notify |
; ret |
@@: |
cmp eax, 16 |
ja @f |
|
mov eax, [ebp+8+new_app_base] |
add eax, new_app_base |
stdcall get_service, eax |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 17 |
ja @f |
stdcall srv_handler,[ebp+8+new_app_base],\ |
[ebp+12+new_app_base],\ |
[ebp+16+new_app_base] |
mov [esp+36], eax |
ret |
;@@: |
; cmp eax, 20 |
; ja @f |
; call CreateSound |
; mov [esp+36], eax |
; ret |
|
@@: |
.fail: |
xor eax, eax |
mov [esp+36], eax |
ret |
|
proc strncmp stdcall, str1:dword, str2:dword, count:dword |
|
mov ecx,[count] |
jecxz .end |
|
mov ebx,ecx |
|
mov edi,[str1] |
mov esi,edi |
xor eax,eax |
repne scasb |
neg ecx ; cx = count - strlen |
add ecx,ebx ; strlen + count - strlen |
|
.okay: |
mov edi,esi |
mov esi,[str2] |
repe cmpsb |
mov al,[esi-1] |
xor ecx,ecx |
|
cmp al,[edi-1] |
ja .str2_big |
je .end |
|
.str1_big: |
sub ecx,2 |
|
.str2_big: |
not ecx |
.end: |
mov eax,ecx |
ret |
endp |
|
|
proc get_proc stdcall, exp:dword, sz_name:dword |
|
mov edx, [exp] |
.next: |
mov eax, [edx] |
test eax, eax |
jz .end |
|
push edx |
stdcall strncmp, eax, [sz_name], 16 |
pop edx |
test eax, eax |
jz .ok |
|
add edx,8 |
jmp .next |
.ok: |
mov eax, [edx+4] |
.end: |
ret |
endp |
|
proc link_dll stdcall, exp:dword, imp:dword |
mov esi, [imp] |
|
.next: |
mov eax, [esi] |
test eax, eax |
jz .end |
|
push esi |
stdcall get_proc, [exp], eax |
pop esi |
|
test eax, eax |
jz @F |
|
mov [esi], eax |
@@: |
add esi, 4 |
jmp .next |
.end: |
ret |
endp |
|
end if |
|
|
|