flat assembler
Message board for the users of flat assembler.
Index
> Projects and Ideas > hash importer Goto page 1, 2 Next |
Author |
|
hidden 02 Mar 2007, 20:18
I wasn't sure? where to post it, to the "windows" or to the "macros", because it relative to both, so I post it to the "Projects and Ideas"
It's a procedure, that find functions in the modules by hashes of the names, and generates jmp table with relative jumps to the imported functions. I could be used in windows applications, dll modules, kernel-mode modules and another PE export compatible files as well. It's absolutely relative, no need reloc section for drivers and dll's, also it saves memory in big import tables. Code: format PE GUI 4.0 entry start include 'win32w.inc' AntiDebug equ ; It's more difficult to debug, then jumps goes not to the begin of the function. But any way OllyDbg doesn't show it as usual. macro rol32 op1, op2 { match =dword v, op1 \{ v = ((v shl op2) or (v shr (32 - op2))) and $FFFFFFFF \} match =word v, op1 \{ v = ((v shl op2) or (v shr (32 - op2))) and $FFFFFFFF \} match =byte v, op1 \{ v = ((v shl op2) or (v shr (32 - op2))) and $FFFFFFFF \} } macro iprc [proc, name] { forward if used proc | impanyway eq if name eqtype '' local ch local hash local length virtual at 0 db name length = $ hash = 0 repeat length load ch byte from length-% rol32 dword hash, 5 hash = hash xor (ch and 11111b) end repeat end virtual label proc dword db length ; Length, if $ff then load lib, if $fe then end, if $fd then by id dd hash else db $fd dd name+1 end if end if } macro iprcex [proc] { forward if used proc | proc eq LoadLibraryA | impanyway eq local ch local hash local length virtual at 0 db `proc#'' length = $ hash = 0 repeat length load ch byte from length-% hash = ((hash shl 5) or (hash shr (32 - 5))) and $FFFFFFFF ; hash = hash rol 5 hash = hash xor (ch and 11111b) end repeat end virtual virtual at $ proc dd ? end virtual db length ; Length, if $ff then load lib, if $fe then end, if $fd then by id dd hash end if } macro hip [proc, len, hash] { forward if used proc | proc eq LoadLibraryA | impanyway eq proc db len dd hash end if } macro imod [module, str] { forward db $fe module dd module#.str - $ module#.text equ str } macro istr [module] { forward module#.str db module#.text, 0 } macro endi ierrproc { db $ff } struct IED Characteristics dd ? ;This field appears to be unused and is always set to 0. TimeDateStamp dd ? ;The time/date stamp indicating when this file was created. Version dd ? ;These fields appear to be unused and are set to 0. Name dd ? ;The RVA of an ASCIIZ string with the name of this DLL. Base dd ? ;The starting ordinal number for exported functions. For example, if the file exports functions with ordinal values of 10, 11, and 12, this field contains 10. To obtain the exported ordinal for a function, you need to add this value to the appropriate element of the AddressOfNameOrdinals array. NumberOfFunctions dd ? ;The number of elements in the AddressOfFunctions array. This value is also the number of functions exported by this module. Theoretically, this value could be different than the NumberOfNames field (next), but actually they're always the same. NumberOfNames dd ? ;The number of elements in the AddressOfNames array. This value seems always to be identical to the NumberOfFunctions field, and so is the number of exported functions. AddressOfFunctions dd ? ;This field is an RVA and points to an array of function addresses. The function addresses are the entry points (RVAs) for each exported function in this module. AddressOfNames dd ? ;This field is an RVA and points to an array of string pointers. The strings are the names of the exported functions in this module. AddressOfNameOrdinals dd ? ;This field is an RVA and points to an array of WORDs. The WORDs are the export ordinals of all the exported functions in this module. However, don't forget to add in the starting ordinal number specified in the Base field. ends ; ZF - Error, ax - Error code AX_WRONG_MODULE_HANDLE equ 'MZ' AX_WRONG_PE_SECTION equ 'PE' AX_WRONG_EXPORT_SECTION equ 'WE' AX_NO_EXPORT_SECTION equ 'NE' AX_FUNCTION_NOT_FOUND equ 'NF' MAX_MOD_MODULE_NAME_LEN = 260 proc ProcIdByHash, base, hash, len ;local img_size dd ? local exp_addr dd ? local exp_end dd ? xchg edi, [base] push ebx ecx edx esi mov ax, 'MZ' cmp [edi], ax jnz .default_error mov edx, [edi+$3C] ; OffSet to PE Header mov ax, 'PE' cmp [edi+edx], ax jnz .default_error ;mov eax, [edi+edx+$50] ; Image size ;mov [img_size], eax mov ebx, [edi+edx+$78] ; Offset to Export section mov eax, [edi+edx+$7C] ; Size of Export section add eax, ebx cmp al, sizeof.IED ; Is export table presents jb .noexport test ebx, ebx ; Is export table presents jz .noexport cmp eax, [edi+edx+$50] ; Is end of export table in image ja .err_wrong_export cmp ebx, [edi+edx+$50] ; Is export table in image ja .err_wrong_export mov [exp_end], eax mov [exp_addr], ebx mov ecx, [edi+ebx+IED.NumberOfNames] mov ebx, [edi+ebx+IED.AddressOfNames] test ecx, ecx ; Any name jz .noexport test ebx, ebx jz .noexport cmp ebx, [exp_end] ja .err_wrong_export lea eax, [ebx+ecx*4] cmp eax, [exp_end] ; Is last name in export table ja .err_wrong_export lea ebx, [edi+ebx-4] .next_export_item: mov esi, [ebx+ecx*4] cmp esi, [exp_end] ja .err_wrong_export movsx eax, byte[len] add eax, esi cmp eax, [exp_end] ja .wrng_length cmp byte[eax+edi], 0 jne .wrng_length add esi, edi mov edx, [hash] @@: lodsb test al, al jz @f and al, 11111b xor dl, al ; Hashing ror edx, 5 jmp @b @@: test edx, edx jz .hash_found .wrng_length: loop .next_export_item mov ax, 'NF' jmp .default_error .hash_found: mov ebx, [exp_addr] lea eax, [ebx+IED.AddressOfNameOrdinals] cmp eax, [exp_end] ja .err_wrong_export mov eax, [edi+eax] cmp eax, [exp_end] ja .err_wrong_export lea eax, [eax+ecx*2-2] cmp eax, [exp_end] ja .err_wrong_export movzx eax, word[eax+edi] ;add eax, edi ;movzx eax, word[eax+ecx*2-2] add eax, [edi+ebx+IED.Base] test eax, eax .end: pop esi edx ecx ebx mov edi, [base] ret .err_wrong_export: mov ax, 'WE' .default_error: xor ebx, ebx jmp .end .noexport: mov ax, 'NE' jmp .default_error endp proc ProcAddrById, base, id local exp_end dd ? xchg edi, [base] push ebx edx ecx esi mov ecx, [edi+$3C] ; OffSet to PE Header mov ebx, [edi+ecx+$78] ; Offset to Export section mov eax, [edi+ecx+$7C] cmp ebx, [edi+ecx+$50] ja .err_wrong_export add eax, ebx mov [exp_end], eax mov esi, [edi+ebx+IED.AddressOfFunctions] mov eax, [id] sub eax, [edi+ebx+IED.Base] lea eax, [esi+eax*4] cmp eax, [exp_end] ja .err_wrong_export mov esi, [edi+eax] ; RVA of function lea eax, [esi+edi] cmp esi, [edi+$50] ; Is this proc in image ja .err_wrong_export cmp esi, ebx jb .proc_found cmp esi, [exp_end] ja .proc_found ; If you don't need Forwarded Export Support you can comment next block stdcall GetForwardedProcId, eax stdcall ProcAddrById, edi, eax jmp .end ; End of block .err_wrong_export: xor ebx, ebx mov ax, 'WE' jmp .end .proc_found: test eax, eax .end: pop esi ecx edx ebx mov edi, [base] ret endp proc GetForwardedProcId, str mov esi, [str] mov ecx, MAX_MOD_MODULE_NAME_LEN sub esp, ecx mov edx, esp mov ebx, esi .next_simbol: lodsb cmp al, '.' jne @f mov ebx, esi @@: mov [edx], al inc edx or al, al jz @f loop .next_simbol @@: cmp ebx, [str] jz .GetProc lea eax, [esp+ebx] sub eax, [str] mov byte[eax-1], 0 stdcall LoadLibraryA, esp mov edi, eax .GetProc: add esp, MAX_MOD_MODULE_NAME_LEN mov esi, ebx neg ebx xor edx, edx @@: lodsb or al, al jz @f and al, 11111b xor dl, al ror edx, 5 jmp @b @@: lea ebx, [ebx+esi-1] lea ecx, [ebx*5] rol edx, cl stdcall ProcIdByHash, edi, edx, ebx ret endp proc GetKernel xor eax, eax mov eax, [fs:eax+30h] test eax, eax js ngk mov eax, [eax+0Ch] mov esi, [eax+1Ch] lodsd mov eax, [eax+8] jmp egk ngk: mov eax, [eax+34h] add eax, 7Ch mov eax, [eax+3Ch] egk: ret endp proc BaseByAddr, addr mov eax, [addr] xor ax, ax @@: cmp word[eax], 'MZ' jz @f sub eax, $10000 jmp @b @@: ret endp proc importer, kernel, imports, loadlib, errproc xchg esi, [imports] xchg edi, [kernel] .loop:lodsb cmp al, $fd ja .more je .byid mov ah, al or edi, edi jz .xxx stdcall ProcIdByHash, edi, [esi], [esi-1] jnz @f cmp ax, 'NF' jnz .endi mov eax, [errproc] test eax, eax jnz .stor mov ax, 'NF' jmp .endi @@: .gbi: stdcall ProcAddrById, edi, eax jnz @f mov eax, [errproc] test eax, eax mov ax, 'WE' jnz @f jmp .endi @@: .stor:if AntiDebug eq cmp word[eax], $FF8B jnz @f add eax, 2 @@: end if sub eax, 4 @@: sub eax, esi mov byte[esi-1], $E9 mov dword[esi], eax .xxx: lodsd jmp .loop .byid:mov eax, [esi] jmp .gbi .more:cmp al, $fe ja .endi lodsd lea eax, [eax+esi-4] invoke loadlib, eax mov edi, eax mov [esi-4], eax jmp .loop .endi:mov edi, [kernel] mov esi, [imports] ret endp proc ImportErrProc stdcall MessageBoxA, 0, wfmsg, wferr, MB_ICONERROR ret endp myi: iprc LoadLibraryA, 'LoadLibraryA',\ AddVectoredExceptionHandler,'AddVectoredExceptionHandler',\ ExitProcess,'ExitProcess' imod user, 'user32' iprcex MessageBoxA,\ ; iprcex if a simbol equal to the name WrongFunc endi xxx = AddVectoredExceptionHandler start: stdcall BaseByAddr, [esp] ;stdcall GetKernel stdcall importer, eax, myi, LoadLibraryA, ImportErrProc jz Error stdcall WrongFunc ; Example of wrong function stdcall MessageBoxA, 0, txt, txt, 0 exit: stdcall ExitProcess, 0 ret Error: mov word[wferr], ax stdcall MessageBoxA, 0, wferr, wferr, 0 jmp exit txt db "It works",0 wferr db ' Error',0 wfmsg db "You'r trying to call wrong function, if it has any arguments then process needs to be restarted.",0 istr user I thick somebody may find it useful And some more, macro emulation of rol, rol sometimes very useful [+] Support forwarding functions. (If anything wrong with it please let me know) [+] If something wrong with module or export tables and errproc = 0 it return error codes, otherwise it call errproc instead of undefined function. Remark: 1) LoadLibraryA should be imported or declared before using "imod" or Forwarding functions, better if it is first this to do. 2) Import table should be in writable executable section, but "istr" can be in read only section. Updates: Added passing needed functions by arguments of importer.
Last edited by hidden on 08 Mar 2007, 20:31; edited 6 times in total |
|||||||||||
02 Mar 2007, 20:18 |
|
f0dder 04 Mar 2007, 12:24
Have you done extensive collision testing of this?
|
|||
04 Mar 2007, 12:24 |
|
vid 04 Mar 2007, 19:33
hidden: that means it doesn't work good enough. You must somehow ensure case when two functions have same hash.
By the way, it is pretty possible to have first 6 chars of 2 different functions same, because many names are prefixed with abbreviation of brand the provide, sometimes just the has abbreviation has 6 chars Last edited by vid on 04 Mar 2007, 19:37; edited 1 time in total |
|||
04 Mar 2007, 19:33 |
|
okasvi 04 Mar 2007, 19:34
Nice macros&procedures
edit: Quote: By the way, it is pretty possible to have first 6 chars of 2 different functions same, because all names are prefixed with abbreviation of brand the provide, sometimes just the has abbreviation has 6 chars crc32 should be enough. |
|||
04 Mar 2007, 19:34 |
|
vid 04 Mar 2007, 19:39
okasvi: still it's not really the best way to leave door open for bugs that may appear long time ago
|
|||
04 Mar 2007, 19:39 |
|
f0dder 04 Mar 2007, 19:44
You should at least check the hashing scheme on all exports of all DLLs in %windir%\system32 - any collision == use another hash algo.
|
|||
04 Mar 2007, 19:44 |
|
okasvi 04 Mar 2007, 20:01
Btw. does this support forwarded exports? If it doesnt it should be noted in first post.
My personal getprocaddr with hashing doesnt, and I first ran into some problems while figuring why it doesnt work on some apis but since I'm the only user of it, it doesnt matter. |
|||
04 Mar 2007, 20:01 |
|
f0dder 04 Mar 2007, 20:05
Not only do you need to support forwarded exports to be able to handle just about any real program running on NT, you also need to handle data exports if you want to support anything linked against dynamic MSVCRT.
|
|||
04 Mar 2007, 20:05 |
|
hidden 04 Mar 2007, 22:59
No, it doesn't support forwarded exports, I don't see an easy way to recognize, is it offset to the function or name to another exports and even if I recognize, I'll have to import that item, and this function would be 3 times bigger. Isn't it more easy to check that function forwarded or not, before using it?
It will make jumps to the data variables, so you will ether need to decompile jumps or use ProcIdByHash, ProcAddrById functions separately, to get adders to the variable. Quote: By the way, it is pretty possible to have first 6 chars of 2 different functions same, because many names are prefixed with abbreviation of brand the provide, sometimes just the has abbreviation has 6 chars Smile CreateDialogIndirect & CreateDialogIndirectParam will have different hashes also it checks sizes. Quote: use another hash algo Algo: Code: 01100-01111-00001-00100-01100-01001-00 xor 010-10010-00001-10010-11001-00001-0000 L o a d L i b r a r y A And then XOR this 2 dwords, it's hash of "LoadLibraryA" Last edited by hidden on 04 Mar 2007, 23:04; edited 1 time in total |
|||
04 Mar 2007, 22:59 |
|
vid 04 Mar 2007, 23:02
You still missed the most important part:
Quote: that means it doesn't work good enough. You must somehow ensure case when two functions have same hash. |
|||
04 Mar 2007, 23:02 |
|
f0dder 04 Mar 2007, 23:14
A data export can be recognized by checking if export RVA is inside a section with PE_SCN_CNT_INITIALIZED_DATA - at least that seems to work, I haven't checked how NT itself handles it.
And forwarded functions could change with a service pack, not to mention that some forwarded functions are useful. I detect a forward by checking if the export RVA lies within PE_DIRENT_EXPORT.rva and PE_DIRENT_EXPORT.size bytes forward - again, dunno how NT itself handles it. |
|||
04 Mar 2007, 23:14 |
|
hidden 05 Mar 2007, 06:13
Here is some more macros&function - Exception handler, I didn't tested it enough, but it works.
Code: macro SetHandler { push TryHandler push dword[fs:0] mov [fs:0], esp push __EXCEPT push ebp } macro UnsetHandler { pop dword[fs:0] add esp, 4 } macro try { __TRY equ local ..endt __ENDT equ ..endt local ..except __EXCEPT equ ..except SetHandler } macro except { add esp, 8 UnsetHandler jmp __ENDT __EXCEPT: UnsetHandler restore __TRY __TRY equ , } macro endt { if __TRY eq add esp, 8 __EXCEPT: UnsetHandler end if __ENDT: restore __EXCEPT restore __ENDT restore __TRY } macro TryProc { proc TryHandler, ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext push esi edi ebx mov esi, [EstablisherFrame] mov edi, [ContextRecord] mov ebx, esi sub esi, 8 add edi, $B4 movsd ; ebp lodsd xchg [edi], eax ;movsd ; eip mov [edi+12], ebx ; esp mov [edi-8], eax ; esp pop ebx edi esi xor eax, eax ret endp } if noinit eq else TryProc end if Quote: You must somehow ensure case when two functions have same hash. Quote: You should at least check the hashing scheme on all exports of all DLLs in %windir%\system32 - any collision == use another hash algo. And my try to check collisions: Code: format PE GUI 4.0 entry start include 'win32a.inc' include 'P:\fasm\asm\tests\utils.inc' MAX_PATH = 260 struct WIN32_FIND_DATA dwFileAttributes dd ? ftCreationTime dq ? ftLastAccessTime dq ? ftLastWriteTime dq ? nFileSizeHigh dd ? nFileSizeLow dd ? dwReserved dq ? cFileName rb MAX_PATH cAlternateFileName rb 14 ends myi: iprcex LoadLibraryA, VirtualAlloc iprcex ExitProcess, LoadLibraryExA, FreeLibrary, FindFirstFileA, FindNextFileA imod user, 'user32' iprcex MessageBoxA endi istr user start: stdcall GetKernel stdcall importer, eax, myi stdcall VirtualAlloc, 0, $10000, MEM_COMMIT, PAGE_READWRITE mov [buf], eax stdcall FindFirstFileA, mask, ffd mov [hfind], eax .loop: try mov edi, [buf] stdcall LoadLibraryExA, ffd.cFileName, 0, LOAD_LIBRARY_AS_DATAFILE cmp eax, 1 jb @f xor si, si xchg si, ax mov ebp, eax call HashAllNames ; base - ebp call CompareHashes @@: endt jz Found stdcall FreeLibrary, ebp .next: stdcall FindNextFileA, [hfind], ffd test eax, eax jnz .loop stdcall MessageBoxA, 0, sNothingFound, sNothingFound, 0 @@: stdcall ExitProcess,-1 Found: stdcall MessageBoxA, 0, sFoundCollision, sFoundCollision, 0 jmp @b proc CompareHashes xor edx, edx @@: inc edx lea edi, [edx*4] add edi, [buf] mov ecx, [count] sub ecx, edx jecxz @f mov eax, [edi-4] repne scasd jne @b ret @@: cmp cl, 1 ; unset ZF ret endp proc HashAllNames pushad cmp word[ebp], 'MZ' jne .wrong mov eax, [ebp+$3C] ; OffSet to PE Header cmp word[ebp+eax], 'PE' jne .wrong mov ebx, [ebp+eax+$78] ; Offset to Export section test ebx, ebx jz .wrong add eax, ebp test si, si jz .running xor edx, edx @@: mov ecx, [eax+edx+$100] ; Virtual Size of the first section add ecx, [eax+edx+$104] ; Virtual Address of the first section cmp ebx, ecx jb @f add edx, $28 jmp @b @@: sub ebp, [eax+edx+$104] ; Section offset in the file add ebp, [eax+edx+$10C] ; Virtual Address of the first section .running: mov ecx, [ebp+ebx+IED.NumberOfNames] test ecx, ecx jz .wrong mov ebx, [ebp+ebx+IED.AddressOfNames] test ebx, ebx jz .wrong add ebx, ebp mov [count], ecx .loop: mov esi, [ebx] add esi, ebp mov edx, esi sub edx, ebp and edx, $7FFFFFFF cmp edx, 10*1024*1024 ja .wrong xor edx, edx @@: lodsb or al, al jz @f and al, 11111b xor dl, al ror edx, 5 jmp @b @@: mov [edi], edx add edi, 4 add ebx, 4 dec ecx jnz .loop .wrong: popad ret endp sFoundCollision db 'Collision has been found',0 sNothingFound db 'Collision not found',0 mask db 'C:\windows\system32\*.dll',0 count dd ? buf dd ? hfind dd ? ffd WIN32_FIND_DATA Result: Collision not found |
|||
05 Mar 2007, 06:13 |
|
f0dder 05 Mar 2007, 13:59
Good
_________________ - carpe noctem |
|||
05 Mar 2007, 13:59 |
|
hidden 05 Mar 2007, 16:33
Quote: how NT itself handles it. If you put "Hardware Access Break Point" at the last "L" on the "NTDLL.RtlAddVectoredExceptionHandler" and try to call GetProcAddress(kernel, 'AddVectoredExceptionHandler'), you will stop at the algo that checks it. |
|||
05 Mar 2007, 16:33 |
|
f0dder 05 Mar 2007, 23:32
can be done only to NTDLL, or is only done to NTDLL? I haven't seen any other redirects, but it would be silly if there was an arbitrary restriction like that?
|
|||
05 Mar 2007, 23:32 |
|
hidden 06 Mar 2007, 00:49
Quote: can be done only to NTDLL, or is only done to NTDLL? |
|||
06 Mar 2007, 00:49 |
|
hidden 06 Mar 2007, 03:23
I added Support forwarding functions, it needs tests and it can be easily disabled by commenting little block.
Also I converted "Collisions Checker" to API extractor Code: format PE GUI 4.0 entry start include 'win32a.inc' include 'P:\fasm\asm\tests\utils.inc' ; - hash importer FILE_WRITE_DATA = 2 myi: iprcex AddVectoredExceptionHandler, LoadLibraryA, VirtualAlloc iprcex ExitProcess, LoadLibraryExA, FreeLibrary, CreateFileA, WriteFile, CloseHandle imod _user, 'user32' iprcex MessageBoxA endi istr _user kernel db 'kernel32',0 kernel_txt db 'kernel32.inc',0 user db 'user32',0 user_txt db 'user32.inc',0 gdi db 'gdi32',0 gdi_txt db 'gdi32.inc',0 shell db 'shell32',0 shell_txt db 'shell32.inc',0 shlwapi db 'shlwapi',0 shlwapi_txt db 'shlwapi.inc',0 advapi db 'advapi32',0 advapi_txt db 'advapi32.inc',0 start: stdcall GetKernel stdcall importer, eax, myi stdcall VirtualAlloc, 0, $10000, MEM_COMMIT, PAGE_READWRITE mov [buf], eax mov esi, kernel mov edi, kernel_txt call GetModImports mov esi, user mov edi, user_txt call GetModImports mov esi, gdi mov edi, gdi_txt call GetModImports mov esi, shell mov edi, shell_txt call GetModImports mov esi, shlwapi mov edi, shlwapi_txt call GetModImports mov esi, advapi mov edi, advapi_txt call GetModImports stdcall MessageBoxA, 0, sDone, sDone, 0 @@: stdcall ExitProcess, -1 .err: stdcall MessageBoxA, 0, sError, sError, 0 jmp @b proc GetModImports stdcall LoadLibraryExA, esi, 0, LOAD_LIBRARY_AS_DATAFILE cmp eax, 1 jb @f mov ebp, eax call HashAllNames ; base - ebp @@: stdcall FreeLibrary, ebp stdcall CreateFileA, edi, FILE_WRITE_DATA, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0 push eax stdcall WriteFile, eax, [buf], [count], esp, 0 stdcall CloseHandle ret endp proc HashAllNames pushad xor si, si xchg si, bp cmp word[ebp], 'MZ' jne .wrong mov eax, [ebp+$3C] ; OffSet to PE Header cmp word[ebp+eax], 'PE' jne .wrong mov ebx, [ebp+eax+$78] ; Offset to Export section test ebx, ebx jz .wrong add eax, ebp test si, si jz .running xor edx, edx @@: mov ecx, [eax+edx+$100] ; Virtual Size of the first section add ecx, [eax+edx+$104] ; Virtual Address of the first section cmp ebx, ecx jb @f add edx, $28 jmp @b @@: sub ebp, [eax+edx+$104] ; Section offset in the file add ebp, [eax+edx+$10C] ; Virtual Address of the first section .running: mov edx, [ebp+ebx+IED.NumberOfNames] test edx, edx jz .wrong mov ebx, [ebp+ebx+IED.AddressOfNames] test ebx, ebx jz .wrong add ebx, ebp mov edi, [buf] .loop: mov esi, [ebx] add esi, ebp mov ecx, esi sub ecx, ebp and ecx, $7FFFFFFF cmp ecx, 10*1024*1024 ja .wrong mov eax, 'hip ' stosd xor ecx, ecx @@: lodsb or al, al jz @f stosb and al, 11111b xor cl, al ror ecx, 5 jmp @b @@: sub esi, ebp sub esi, [ebx] ; esi - length lea eax, [esi-1] mov esi, ecx lea ecx, [eax*5] rol esi, cl mov ecx, esi call db2str shl eax, 16 mov ax, ',$' stosd rol ecx, 8 xor ah, ah mov al, cl call db2str shl eax, 16 mov ax, ',$' stosd rol ecx, 16 xor ah, ah mov al, cl call db2str shl eax, 16 xor ah, ah mov al, ch call db2str stosd mov eax, $0A0D0000 rol ecx, 8 xor ah, ah mov al, cl call db2str stosd add ebx, 4 dec edx jnz .loop sub edi, [buf] mov [count], edi .wrong: popad ret endp proc db2str ; ax - input/output ror ax, 4 shr ah, 4 add ax, ('0' shl 8) + '0' cmp al, '9' jna @f add al, 'A' - '9' - 1 @@: cmp ah, '9' jna @f add ah, 'A' - '9' - 1 @@: ret endp sError db 'Some Error',0 sDone db 'Done',0 count dd ? buf dd ? Than you can use importer like this: Code: format PE GUI 4.0 entry start include 'win32a.inc' include 'P:\fasm\asm\tests\utils.inc' myi: include 'kernel32.inc' imod user, 'user32' include 'user32.inc' endi istr user start: stdcall GetKernel stdcall importer, eax, myi stdcall MessageBoxA, 0, sWorks, sWorks, 0 stdcall ExitProcess, -1 sWorks db 'It works!!!',0 |
|||
06 Mar 2007, 03:23 |
|
Vasilev Vjacheslav 06 Mar 2007, 14:43
hidden, why you don't create one simple archive which contains you work attached to the first post?
|
|||
06 Mar 2007, 14:43 |
|
vid 06 Mar 2007, 14:59
hidden: so, if once there will be some collision, how will your app beheave?
|
|||
06 Mar 2007, 14:59 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.