· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› LoadLibrary

. 1 . 2 . >>

Посл.отвђт Сообщенiе


Дата: Мар 26, 2004 17:53:45

Вот такие вещи, конечно, хороши:
.386

.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

.data
MsgBoxCaption  db "Iczelion Tutorial No.2",0
MsgBoxText     db "Win32 Assembly is Great!",0

.code
start:

invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK
invoke ExitProcess, NULL
end start

Но хочется подобное сделать в tasm, т.е. без использования include. Обычный call, ну или invoke, если он есть в tasm. А нужные процедуры взять через LoadLibrary. Вопрос : как без *.inc и *.lib реализовать то, что указано в примере? Все константы описываются в самом asm-коде или также берутся из dll. Если можно киданите полнотекстовый код. Заранее спасибо.


Дата: Мар 26, 2004 18:05:21

Без inc вполне можно обойтись, описав прототипы и избавившись от фенечек типа addr и т.д. А вот без lib фиг ты обойдешься. А если приспичило, то придется пользоваться LoadLibrary/GetProcAddress. Только к чему такие извраты...


Дата: Мар 26, 2004 18:12:01

Прошу прощения, что сразу не указал. Мне именно примерчик с LoadLibrary+GetProcAddress и нужен.


Дата: Мар 26, 2004 20:28:44 · Поправил: S_T_A_S_

startinger
Посмотрите тут Если не хотите, чтобы в таблице импорта был GetProcAddress (хотя NT что-то все равно требует) - пишите в первой строке [ESP] - должно работать


Дата: Мар 26, 2004 21:06:46

Постойте-ка, я же указывал tasm, а там fasm, я, конечно увидел там вызов MessageBox и ExitProcess, но защёт чего это?
usedll user32-это что ли или я неправильно понял?


Дата: Мар 26, 2004 22:04:13

К слову: Вызов Win32 API на TASM32 всегда выливается в CALL, который приводит к JMP, который только затем попадает в системную DLL. Была статья по использованию _imp_xxx@xxx, но такое, похоже, работает только в MASM. Так что если сделать такой объект:
API struc
  impl_CreateWindowEx
  impl_ShowWindow
  impl_UpdateWindow
  impl_GetDlgItem
  ; --- etc.
API ends

.DATA
api API <?>

.CODE
; --- Use LoadLibrary()/GetProcAddress() to
; --- initialize members of 'api' object

...

push IDC_EDIT1
push hDlg
call api.impl_GetDlgItem
mov  hEdit, eax

Тогда все вызовы API будут напрямик по адресу (без лишнего JMP) Не знаю, насколько это практичнее.


Дата: Мар 26, 2004 23:44:04

AsmGuru62 wrote:
 .CODE
; --- Use LoadLibrary()/GetProcAddress() to
; --- initialize members of 'api' object 

А можно этот фрагмент поподробнее...


Дата: Мар 26, 2004 23:48:49

startinger

Ну лентяй, ну просто феномен. Читай:

http://doc.ddart.net/asm/Microsoft_MASM_Programmers_Guide_v6.1/Chap_10 .htm

В сети полезно рыскать, перед тем как ТАКИЕ вопросы задавать!


Дата: Мар 26, 2004 23:58:45 · Поправил: startinger

volodya wrote:
В сети полезно рыскать, перед тем как ТАКИЕ вопросы задавать!

Я так и сделал вообще-то, но толкового не нашёл ничего. Правда, лазил не по асмовым сайтам, а в Google.

Огромное спасибо. Буду пробовать.


Дата: Мар 27, 2004 00:04:21

Хе, а я, выходит, тебе эту ссылку не из гугла вытащил? Ну-ну.


Дата: Мар 27, 2004 08:29:43 · Поправил: S_T_A_S_

startinger

Я ваш вопрос понял так:
Мне именно примерчик с LoadLibrary+GetProcAddress и нужен.

Смысл по той ссылке такой: есть список используемых API (IMPORTED_NAMES: ..)
Этот список обрабатывается тем кодом и строится таблица (LOCKUP_TABLE) для косвенных вызовов функций.

Для вышего случая заполняем ручками таблички так:
MPORTED_NAMES:
db "LoadLibraryA",0	;;  это из kernel32.dll
db "ExitProcess",0	;;  это из kernel32.dll
db 0 - конец списка функций для dll
db "user32.dll",0	;;  новая dll
db "MessageBoxA",0
db 0FFh - конец таблицы

LOCKUP_TABLE:
LoadLibrary	dd ?
ExitProcess	dd ?
MessageBox	dd ?


После того, как код отработает и заполнит LOCKUP_TABLE, можно будет вызывать функции из dll косвенными вызовами:
push	MB_OK
push	MsgBoxCaption
push	MsgBoxText
push	NULL
call	[MessageBox] 

Какие-то конкретные особенности TASM'а я к сожалению не знаю, как например компилить/линковать это все будете, а в FASM я написал макросы для избавления от такой вот рутины, если интересно, то пример использования + все макросы есть здесь


Дата: Мар 27, 2004 09:53:10

S_T_A_S_
Привет! Что-то не пишешь мне? У,кстати, Windows накрылся и с ним все письма и вообще много чаво.
startinger
У меня есть подобный пример для MASM и для NASM. Если нужно - кидай адресс.


Дата: Мар 27, 2004 11:54:32

2 1990 адрес Кидай!


Дата: Мар 27, 2004 20:28:06

1990 мне дал достаточно неплохие коды, там просто загружаются адреса функций в память, но идентификация функций происходит по checksum, а хотелось бы по имени.
вот такой код:
;; EDX must hold the offset of the MZ header, EBX the checksum
FindAPI:
        push    edx                             ;; Preserve the value in EDX
        mov     DLLStart, edx                   ;; keep the offset for later use
        mov     ecx, [edx+3Ch]                  ;; PE header
        add     ecx, edx                        ;; Normalize offset
        mov     PEStart, ecx                    ;; Keep PEStart for later use
        mov     ecx, [ecx+78h]                  ;; Pointer to Export Table
        add     ecx, edx                        ;; Normalize offset
        mov     ExportStart, ecx                ;; Keep pointer to Export table for later use
        mov     edx, [ecx+18h]                  ;; Number of Exports
        mov     ecx, [ecx+20h]                  ;; Pointer To Pointer to Exports Names
        add     ecx, DLLStart                   ;; Normalize offset
@Loop:
        xor     edi, edi                        ;; EDI will hold the checksum
        mov     esi, [ecx]                      ;; Pointer To Export #n
        add     esi, DLLStart                   ;; Normalize offset
        xor     eax, eax
        push    ecx

@Loop2:
        lodsb                                   ;; Load char of API name into esi
        mov     ecx, eax

        add     edi, eax                        ;; checksum of API name - Part 1
        rol     edi, cl                         ;; checksum of API name - Part 2
        test    eax, eax                        ;; if byte was not the 0-byte...
        jne     @Loop2                          ;; ...keep looping
        pop     ecx
        cmp     edi, ebx                        ;; Checksum found ?
        je      @Found                          ;; API found

        add     ecx, 4                          ;; Next pointer to API Name
        dec     edx                             ;; Still APIs to go?
        jne     @Loop                           ;; If so, jump
        pop     edx                             ;; Clean the stack
        xor     eax, eax                        ;; return 0 means "API not found"
        ret

@Found:
        mov     eax, DLLStart                   ;; Here we need...
        mov     ecx, ExportStart                ;; the saved values again
        mov     ebx, [ecx+18h]                  ;; Number of Exports
        mov     ecx, [ecx+24h]                  ;; Pointer To Ordinals
        add     ecx, eax                        ;; Normalize offset
        sub     ebx, edx                        ;; EBX = Number of Ordinals - API we want
        shl     ebx, 1                          ;; The ordinal table is made of WORD values - we have to multiply with 2
        add     ecx, ebx                        ;; Pointer to the ordinal of the API
        movzx   ebx, word ptr [ecx]             ;; Ordinal of our API
        mov     ecx, ExportStart                ;; And the Export Start again
        mov     ecx, [ecx+1Ch]                  ;; Offset Table
        add     ecx, eax                        ;; Normalize offset
        shl     ebx, 2                          ;; Expand to DWORD size
        add     ecx, ebx                        ;; Point to offset where our API begins
        add     eax, [ecx]                      ;; Add that offset to the beginning of the DLL
        pop     edx                             ;; Clean the stack
        ret

Как бы это сделать, чтобы сюда передавать не checksum, а имя функции, к примеру MessageBoxA.


Дата: Мар 28, 2004 10:46:32

startinger

но идентификация функций происходит по checksum, а хотелось бы по имени.
Как бы это сделать, чтобы сюда передавать не checksum, а имя функции, к примеру MessageBoxA.

Мой пример как раз делает то, что вам надо. (на ТАСМ синтаксис я вроде исправил)
И добавте еще строки из моего предыдущего поста

Еще вероятно в TASM придется возиться с линкером - поэтому я и рекомендовал пример на FASM, ка самый простой в данном случае. Синтаксис там такой же как IDEAL в ТАСМ, как я знаю.

Если я правильно понял вашу тему - вы хотите избавиться от секции импорта?
Еще очень желательно почитать (хотябы Iczelion) про PE формат. Все это есть на сайте.
	mov	ebx,	[ESP]	;; наша прога вызавается call из kernel32.dll
	mov	EBP, 	ebx
@@:	xor	bx,	bx	;; выравниваем адрес dlls XXXX0000h
	cmp	WORD[ebx],'ZM'	;; ищим подпись PE
	jz	@f		;; Kernel32.dll найден
	dec  	ebx		;; смотрим назад. Сейчас -1, ^^ все равно выравняем адрес 10000h
	jmp	@b
;; здесь имеем в EBX - адрес загрузки kernel32.dll
@@:	cld
	mov	EDI, IMPORTED_NAMES	;;  таблица с именами ф-ций
	mov	ESI, LOCKUP_TABLE	;;  таблица адресов для ф-ций
@@:	push	EDI
	push	EBX
	call	EBP	;;  вызываем GetProcAddress
;;	stdcall	EBP, EBX, EDI	;;  вызываем GetProcAddress
	mov	[ESI], eax	;;  сохраняем адрес ф-ции в таблице Locup Table
	add	ESI,	4	;;  следующий адрес в Locup Table
;;  ищем следующее импортируемое имя
@@s:	xor	al, al
	mov	ecx, edi	;;  макс. длина строки
	repnz	scasb		;;  ищем 0
	cmp	[EDI], al
	js	..ENTRY_POINT	;;  переходим к нашей программе
	jnz	@b		;;  нашли имя ф-ции
;;  нашли имя dll
	inc	EDI
	push	EDI
	call	[LoadLibrary]	;;  адрес в таблице уже прописан
;;	invoke	LoadLibrary, EDI
	mov	EBX, eax	;;  адрес базы новой dll 
	jmp	@@s	 }



1990
Чего писать-то? Щас оперу пишу.. И про тебя напишу ;-)

. 1 . 2 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.075