We generally get the address of a function, usually in clear text, such as defining an API function string "MessageBoxA", and then comparing one byte in the GetProcAddress function to one byte. This is a lot of drawbacks, such as if we define an anti-virus software is more sensitive to the API function string, then it may increase the antivirus software to our program's decision value, and the definition of these strings there is a disadvantage is the large number of bytes occupied. Let's think about how our API function string is defined by the algorithm as a 4-byte value, and then in GetProcAddress the API string that points to each address in the Addressofnames table is compressed into 4-byte values by our algorithm, With the 4-byte value we defined earlier, the function address is read if the match succeeds.
Let's look at a Rol 3 shift algorithm, which moves the destination address loop to the left 3 bits at a time, and then makes the low byte different from each byte of the source string. The algorithm is very compact and convenient. There are many convenient and compact algorithms, such as the Ror 13 algorithm, in fact, it is basically the same as our above, except that it will be the function name table string through our algorithm process to obtain the hash value and the hash value we defined before the match, the match succeeds to obtain the corresponding function address.
The following code runs CLAC with the hash search WinExec function:
.386. Model flat, stdcall optionCaseMap:none include Windows.Incinclude User32.Incinclude KERNEL32.Incincludelib user32.lib includelib kernel32.lib. Const SZCALC DB'calc.exe',0. Code _GETKRNL32 proc;>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>;get the address of the Kernel32.dll because XP and Win7 are not the same;Therefore, the way to obtain the address by the comparison name, see Kernel32 Base site for learning;http://blog.csdn.net/programmingring/article/details/11357393;>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>AssumeFS: NothingmoveaxFS:[30h]moveax, [eax + 0ch]movEAX, [eax + 1ch];The first of the Ldr_module ;>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>;Unicode string pressed into the Kernel32.dll;>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>> PushDWORD ptr 006chPushDWORD ptr 6c0064hPushDWORD ptr 2e0032hPushDWORD ptr 33006chPushDWORD ptr 65006ehPushDWORD ptr 720065hPushword ptr 006bhmovEBX, ESP;ebx pointing to a string ;>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>;Start comparing;>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>_search: CMPeax0 JZ_notfoundCMPeax, 0ffffffffhJZ_notfoundLeaESI, [eax + 1ch];esi points to the unicode_string structure XORecx, ecxmovCx - ;the length of the comparison movESI, [esi +4];get the buffer member of the unicode_string structure movEDI, EBX;EDI pointer to Kernel32unicode string RepZ CMPSW orECX, ECX;ecx minus the description equal JZ_foundmovEAX, [EAX];Get Next Ldr_module jmp_search_notfound: moveax, 0ffffffffhjmp_over_found: movEAX, [eax + 08h];Get Address _over: AddEsp - ret_getkrnl32 ENDP _getrolhash proc _lpapistringmoveax, _lpapistringPushESIXORedx, edxXchgEAX, ESI;esi = _lpapistring CLD ;Increment _next: LODSB ;take a single character from the address that ESI points to TestAl, AL;whether the comparison is 0 JZ_retRolEdX3 ;left loop shift 3 bit XORDL, AL;low byte and character Xor jmp_next_ret: XchgEAX, edx;EAX = Hash of the processed _lpapistring PopESIret_getrolhash ENDP _getapi proc _hdllhandle, _ihashapiPushEBPmoveax, _hdllhandlemovecx, _ihashapimovebx, eaxmovEDI, ECXmoveax, [ebx + 3ch]movESI, [ebx + eax + 78h];Get Export RVA Leaesi, [esi + ebx + image_export_directory. Numberofnames]LODSD XchgEAX, edx;edx = Numberofnames LODSD Pushfa[;[ESP] = addressoffunctions LODSD XchgEAX, EBP;EBP = Addressofnames LODSD XchgEAX, EBP;EBP = addressofnameordinals, eax = Addressofnames Addeax, ebxXchgEAX, ESI;esi = addressofnames _loopscas: DecedxJS_retLODSD ;EAX = RVA of API name AddEAX, EBX;EAX = Actual address of the API name Pushedx invoke _getrolhash, eax;Calculate Hash String PopedxCMPEAX, EDI;Compare and pass-through hash parameters are equal JZ_getaddrAddEbp2 ;increment, and esi corresponds jmp_loopscas_getaddr: MOVZXEAX, Word ptr [ebp + ebx];get the ordinal value SHLeax2 ;by 4 AddEAX, [ESP];The value of the position of the corresponding ordinal value in the Addressoffunctions movEAX, [ebx + eax];Get function Address Addeax, ebx_ret: PopecxPopEBPret_getapi ENDP _winmain proc Invoke _getkrnl32 invoke _getapi, eax, 016EF74BH;The hash of "WinExec" PushSw_showLeaebx, SzcalcPushebxPagereaxret_winmain ENDPStart: Pager_winmain invoke ExitProcess,0End Start
The implementation of the API function address obtained by the hash algorithm search