(1)strlen(char *s)
.386 .model flat, stdcall include kernel32.inc includelib kernel32.lib include msvcrt.inc includelib msvcrt.lib .data szText db "Reverse Engineering", 0 format db "length = %d", 0AH, 0 .code main PROC LEA EDI, szText MOV ECX,0FFFFFFFFH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XOR AL, AL MOV EBX, EDI REPNE SCASB INC EDI SUB EDI, EBX ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INVOKE crt_printf, addr format, EDI INVOKE crt_getchar INVOKE ExitProcess, 0 main ENDP END main
Set eax to 0 and use scasb to compare the value of edi with that of eax until the data stored at the address specified by edi is'/0', that is, stop the loop at the end of the string, then subtract from the original position of edi (ebx) and subtract the 1 occupied by'/0', that is, the length of the string, the result is 19.
(2)strchr(const *char s)
.386 .model flat, stdcall include kernel32.inc includelib kernel32.lib include msvcrt.inc includelib msvcrt.lib .data szText db "Reverse Engineering", 0 chr db 'i' format db "%d", 0AH, 0 .code main PROC LEA EDI, szText MOV ECX,0FFFFFFFFH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV EBX,EDI MOV EAX,i REPN SCASB INC EBX SUB EDI,EBX ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INVOKE crt_getchar INVOKE ExitProcess, 0 main ENDP END main
With scasb, the value of chr is given to eax. When scas stops, it is the position where chr first appears. Returning the difference between this position and the original position is the answer.
(3)strcmp(const *s,const *c)
.386 .model flat, stdcall include kernel32.inc includelib kernel32.lib include msvcrt.inc includelib msvcrt.lib .data format db "%d", 0AH, 0 szText db "Reverse Engineering", 0 szText2 db "Reverse Engineering", 0 ;szText==szText2 szText3 db "Reverse Eng", 0 ;szText>szText3 szText4 db "Reverse Engj", 0 ;szText<szText4 szText5 db "Reverse Engh", 0 ;szText>szText5 .code main PROC LEA ESI, szText LEA EDI, szText2 ;result=0 ;LEA EDI, szText3 ;result=1 ;LEA EDI, szText4 ;result=-1 ;LEA EDI, szText5 ;result=1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; START: XOR ECX,ECX MOV EAX,[ESI+ECX] MOV EBX,[EDI+ECX] CMP EAX,EBX JC s1 JNC s2 JZ s3 s1: MOV EAX,1 JMP HALT s2: MOV EAX,-1 JMP HALT s3: CMP EAX,0 JZ s4 JMP START s4: MOV EAX,0 JMP STOP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INVOKE crt_printf, addr format, EAX INVOKE crt_getchar INVOKE ExitProcess, 0 main ENDP END main
If the former is larger than the latter, then jump to s1, output result 1, if the former is smaller than the latter, then jump to s2, output-1, if equal, then jump to s3, judge whether the character is 0, if 0, that means the end of the string, output result 0, if not 0, then the string does not end, move forward to the next bit. Row comparison.
(4)strset(char *s,char c)
.386 .model flat, stdcall include kernel32.inc includelib kernel32.lib include msvcrt.inc includelib msvcrt.lib .data szText db "Reverse Engineering", 0 ; chr db 'j' ; .code main PROC LEA EDI, szText LEA ESI, chr MOV ECX,0FFFFFFFFH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV EBX, [ESI] L: MOV AX, [EDI] CMP AL, 0 JZ STOP MOV [EDI], BL INC EDI LOOP L STOP: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INVOKE crt_printf, addr szText INVOKE crt_getchar INVOKE ExitProcess, 0 main ENDP END main
Experimentation: Documents and Functions Used
TestHook.cpp
#include "stdio.h" #include "conio.h" #include "windows.h" typedef void (*PFN_HOOKSTART)(); typedef void (*PFN_HOOKSTOP)(); void main() { HMODULE hDll = NULL; PFN_HOOKSTART HookStart = NULL; PFN_HOOKSTOP HookStop = NULL; hDll = LoadLibraryA("HookDll.dll"); // Loading HookDll.dll if( hDll == NULL ) return; // Get the addresses of the derived functions HookStart() and HookStop() HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, "HookStart"); HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, "HookStop"); HookStart(); //Start hooking keyboard messages // Wait until the user enters'q'to terminate the hook printf("press 'q' to quit!\n"); while( _getch() != 'q' ) ; HookStop(); //Termination of hook fetching keyboard messages FreeLibrary(hDll); //Unload HookDll.dll }
Load HookDll.dll to the current process
Call the HookStart() function to start hooking
Waiting for the user to enter'q'
Call the HookStop() function to terminate hooking
HookDll.cpp
#include "stdio.h" #include "windows.h" HINSTANCE g_hInstance = NULL; HHOOK g_hHook = NULL; HWND g_hWnd = NULL; BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved){ switch( dwReason ){ case DLL_PROCESS_ATTACH: g_hInstance = hinstDLL; break; case DLL_PROCESS_DETACH: break; } return TRUE; } LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){ char szPath[MAX_PATH] = {0,}; char *p = NULL; if( nCode >= 0 ) { // bit 31 : 0 => press, 1 => release if( !(lParam & 0x80000000) ){ GetModuleFileNameA(NULL, szPath, MAX_PATH); p = strrchr(szPath, '\\'); //If the executable file name of the process loading the current DLL is notepad.exe, the message will not be passed to the next hook. if( !_stricmp(p + 1, "notepad.exe") ) return 1; } } // The current process is not notepad.exe, passing messages to the next hook return CallNextHookEx(g_hHook, nCode, wParam, lParam); } #ifdef __cplusplus extern "C" { #endif __declspec(dllexport) void HookStart() { g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0); } __declspec(dllexport) void HookStop() { if( g_hHook ) { UnhookWindowsHookEx(g_hHook); g_hHook = NULL; } } #ifdef __cplusplus } #endif
KeyboardProc() callback function: When the keyboard key is released, check whether the process loading HookDll.dll is notepad.exe, if it is, return 1; if not, call CallNextHookEx() to pass the message to the application or the next hook.
First: try testhook and hookdll first, and create a new solution in VS to copy hookdll for reference under the project. Generation and Use of VS2017 Dynamic Link Library (.dll) The solution of generating hookdll is to find the generated DLL in the directory, create a new console program to copy the testhook to generate exe file, rename the DLL copy and rename it HookDll.dll to run the EXE file in the same directory as exe to check the effect. It is found that the hook ticks the keyboard input until the end of the q input.
Now that's the main work of modifying hookdll's code implementation requirements:
The main parameters of Keyboard HookProc function are as follows:
nCode. Type of message, HC_ACTION
The status of keys (press or pop up) WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP
lParam: A pointer to the Keyboard HookStruct structure, which contains key details.
Code section: Remove return 1, even in notepad, the keys will be released instead of the previous hook, and then as shown in Figure 1
Read the input characters and store them in the file d:\key.txt. Generate test:
Run testhook.exe to load the hook and open notepad input
To the D-disk catalog
Reference resources A simple keyboard hook program