;================================================================================= ; koupd 0.1 ; ; Utility for generating/updating symversion and modinfo information ; ; ! Currently only symversion information is being generated. ; ; The LSCR Project. ;================================================================================= format ELF include '../samples/macros.inc' include '../include/symbols.inc' include '../include/structs.inc' extrn error_chk section '.text' executable public _start _start: pop eax pop edx cmp eax, 2 jge fixit usage: mov eax, SYS_WRITE ; print usage info mov ebx, STDOUT mov ecx, usage_s mov edx, usage_s_sz int 0x80 exit: mov eax, SYS_EXIT xor ebx, ebx int 0x80 fixit:;-----------------------------------------------------------------; pop ebx mov eax, SYS_OPEN ; open and read the source file mov ecx, O_RDWR or O_APPEND int 0x80 test eax, eax jnz @f mov eax, 0x80000000 @@: ccall error_chk, <"Cannot open source file: SYS_OPEN->">, exit mov [file_d], eax mov eax, SYS_FSTAT mov ebx, [file_d] mov ecx, fstat int 0x80 ccall error_chk, <"Cannot access source file: SYS_FSTAT->">, close mov eax, [fstat.st_size] ; src size mov [fsize1], eax mov eax, SYS_BRK xor ebx, ebx int 0x80 ccall error_chk, <"Failed to allocate memory: SYS_BRK->">, close mov [ptr1], eax mov ebx, [fstat.st_size] add ebx, eax mov eax, SYS_BRK int 0x80 ccall error_chk, <"Failed to allocate memory: SYS_BRK->">, close mov eax, SYS_READ mov ebx, [file_d] mov ecx, [ptr1] mov edx, [fstat.st_size] int 0x80 ccall error_chk, <"Failed to read source file: SYS_READ->">, close mov eax, SYS_UNAME mov ebx, utsname int 0x80 ccall error_chk, <"Failed to obtain kernel information: SYS_UNAME->">, close ;---------------------------------------------------------------; try to open Module.symvers mov esi, path1 ; construct '/lib/modules//build/Module.symvers' mov edi, utsname.release sub edi, path1_sz mov ebx, edi mov ecx, path1_sz rep movsb xor eax, eax @@: scasb jne @b mov esi, path2 dec edi mov ecx, path2_sz rep movsb mov eax, SYS_OPEN mov ecx, O_RDONLY int 0x80 test eax, eax jnz @f mov eax, 0x80000000 @@: ccall error_chk, <"Cannot open Module.symvers. Make sure you have kernel-devel installed. SYS_OPEN->">, close mov [filesym_d], eax mov eax, SYS_FSTAT mov ebx, [filesym_d] mov ecx, fstat int 0x80 ccall error_chk, <"Cannot access source file: SYS_FSTAT->">, extrn_done mov eax, SYS_BRK xor ebx, ebx int 0x80 ccall error_chk, <"Failed to allocate memory: SYS_BRK->">, extrn_done mov [bss_original2], eax mov ebx, [fstat.st_size] add ebx, eax mov eax, SYS_BRK int 0x80 ccall error_chk, <"Failed to allocate memory: SYS_BRK->">, extrn_done mov eax, SYS_READ mov ebx, [filesym_d] mov ecx, [bss_original2] mov edx, [fstat.st_size] int 0x80 ccall error_chk, <"Failed to read source file: SYS_READ->">, extrn_done next_sym:;--------------------------------------------------------------; search for an extrn symbol mov eax, [ptr1] mov [source_ptr], eax mov eax, [fsize1] mov [source_size], eax mov [pattern_ptr], _extrn mov [pattern_size], _extrn_sz call PatternSearch_KMP test eax, eax js extrn_done sub [fsize1], eax ; decrement remaining size mov esi, [ptr1] add [ptr1], eax add [ptr1], _extrn_sz add esi, eax mov edi, esi ; make sure it's a correct 'extrn' @@: dec edi cmp [edi], byte 0xa je @f cmp [edi], byte 0x20 je @b cmp [edi], byte 0x09 je @b jmp next_sym @@: add esi, _extrn_sz-1 @@: inc esi cmp [esi], byte 0x20 je @b cmp [esi], byte 0x09 je @b ; edi = pointer to the symbol name mov edx, esi dec edx @@: inc edx cmp [edx], byte 0x20 je @f cmp [edx], byte 0x09 je @f cmp [edx], byte 0x0a jne @b @@: sub edx, esi mov eax, [bss_original2] mov [ptr2], eax mov eax, [fstat.st_size] mov [fsize2], eax mov [pattern_ptr], esi mov [pattern_size], edx wrong_sym:;-------------------------------------------------------------; search for the symbol within Module.symvers mov eax, [ptr2] mov [source_ptr], eax mov eax, [fsize2] mov [source_size], eax call PatternSearch_KMP test eax, eax js next_sym add eax, [source_ptr] ; eax = our symbol candidate mov edi, eax sub [fsize2], eax cmp [edi-1], byte 0x09 ; make sure it's indeed the desired symbol je @f cmp [edi-1], byte 0x20 je @f inc edi mov [ptr2], edi jmp wrong_sym @@: add eax, [pattern_size] cmp [eax], byte 0x09 je @f cmp [eax], byte 0x20 je @f inc edi mov [ptr2], edi jmp wrong_sym @@: dec edi ; scan backwards for a "0x" cmp [edi], word "0x" jne @b cmp [sect], 1 ; we need to define the section only once je @f mov eax, SYS_WRITE mov ebx, [file_d] mov ecx, hdr1 mov edx, hdr1_sz int 0x80 mov [sect], 1 @@: mov eax, SYS_WRITE mov ebx, [file_d] mov ecx, hdr_entry1 mov edx, hdr_entry1_sz int 0x80 mov eax, SYS_WRITE mov ebx, [file_d] mov ecx, edi mov edx, 10 int 0x80 mov eax, SYS_WRITE mov ebx, [file_d] mov ecx, hdr_entry2 mov edx, hdr_entry2_sz int 0x80 mov eax, SYS_WRITE mov ebx, [file_d] mov ecx, [pattern_ptr] mov edx, [pattern_size] int 0x80 mov eax, SYS_WRITE mov ebx, [file_d] mov ecx, hdr_entry3 mov edx, hdr_entry3_sz int 0x80 jmp next_sym ;-----------------------------------------------------------------------; should parse here fo modinfo and update appropriate entries.... extrn_done: mov eax, SYS_CLOSE mov ebx, [filesym_d] int 0x80 close: mov eax, SYS_CLOSE mov ebx, [file_d] int 0x80 jmp exit ;==================================================================================== ; searches for a pattern within the source buffer using Knuth-Morris-Pratt algorithm. ; The maximum size of mismatch table is 128 bytes those pattern array length should ; be no longer. Hopefully we don't have any symbols longer than that. ; ; ; 1. mismatch table compute algorithm: ; ; i = 0 ; j = -1 ; m = pattern length ; ; next[0] = -1 ; ; while (i < m-1) ; { ; if (j == -1) || (pattern[i] == pattern[j]) ; { ; i = i+1 ; j = j+1 ; next[i] = j ; } ; ; else j = next[j] ; } ; ; ; 2. pattern search algorithm: ; ; i = 0 ; j = 0 ; m = pattern length ; n = source length ; result = ? ; ; while (j < n) && (i < m) ; { ; while (i > -1) && (pattern[i] != source[j]) i = next[i] ; i = i+1 ; j = j+1 ; } ; ; if (i = m) result = j-m ; else result = -1 ; ; ; parameters: [source_ptr] - pointer to the source buffer ; [source_size] - size of the source buffer ; [pattern_ptr] - pointer to buffer with pattern to search for ; [pattern_size] - size of the pattern ; returns: EAX = offset into the match within the source, -1 if no match. ;============================================================================================================ PatternSearch_KMP: pushad mov esi, [pattern_ptr] mov edx, next_tbl mov edi, [pattern_size] cmp edi, 128 jge negative dec edi xor ecx, ecx xor eax, eax mov cl, byte -1 mov [edx], dword -1 @@: mov bl, byte [esi+eax] test cl, cl js .lab cmp bl, byte [esi+ecx] jne .l1 .lab: inc cl inc eax mov [edx+eax], byte cl jmp .lk .l1: mov cl, byte [edx+ecx] .lk: cmp eax, edi jb @b mov edi, [source_ptr] xor eax, eax xor ecx, ecx .poi: mov bl, byte [edi+ecx] test al, al js @f cmp bl, byte [esi+eax] je @f mov al, byte [edx+eax] jmp .poi @@: inc ecx inc al cmp ecx, [source_size] je @f cmp al, byte [pattern_size] jne .poi @@: cmp al, byte [pattern_size] jne negative sub ecx, eax mov [tmpv], ecx popad mov eax, [tmpv] ret negative: popad mov eax, -1 ret section '.data' writeable usage_s db "koupd v0.1 (c) 2006 Roman Ovseytsev.",0xa db "Utility for generating/updating symversion and modinfo information",0xa,0xa db "USAGE:",0xa db " ./koupd ",0xa usage_s_sz = $-usage_s path1 db "/lib/modules/" path1_sz = $-path1 path2 db "/build/Module.symvers",0 path2_sz = $-path2 _extrn db "extrn" _extrn_sz = $-_extrn hdr1 db 0xa,0xa,"section '__versions' align 32",0xa,0xa,"____versions:",0xa hdr1_sz = $-hdr1 hdr_entry1 db "@@: dd " hdr_entry1_sz = $-hdr_entry1 hdr_entry2 db 0xa, ' db "' hdr_entry2_sz = $-hdr_entry2 hdr_entry3 db '"',0xa," db 64-($-@b) dup(0)",0xa,0xa hdr_entry3_sz = $-hdr_entry3 sect dd 0 ptr1 rd 1 ptr2 rd 1 tmpv rd 1 source_ptr rd 1 source_size rd 1 pattern_ptr rd 1 pattern_size rd 1 file_d rd 1 filesym_d rd 1 fsize1 rd 1 fsize2 rd 1 bss_original2 rd 1 fstat stat utsname old_utsname next_tbl rb 128