0,0 → 1,492 |
format PE GUI 4.0 |
section '.text' code readable executable |
entry start |
start: |
xor ebx, ebx |
mov esi, a2_src |
mov edi, a2 |
movsd |
movsd |
movsd |
movsd |
movsd |
push 1 |
call [SetErrorMode] |
push ebx ; lpParam |
push 400000h ; hInstance |
push ebx ; hMenu |
push ebx ; hWndParent |
push 100 ; nHeight |
push 200 ; nWidth |
mov eax, 80000000h |
push eax ; y |
push eax ; x |
push 10EF0140h ; dwStyle |
push WndName |
push ClassName |
push 388h ; dwExStyle |
call [CreateWindowExA] |
xchg edi, eax |
push 0Ah ; OEM_FIXED_FONT |
call [GetStockObject] |
push ebx |
push eax |
push 30h ; WM_SETFONT |
call ListCommand |
call CollectDrivesInfo |
push MyWndProc |
push -4 ; GWL_WNDPROC |
push edi |
call [SetWindowLongA] |
mov [OldWndProc], eax |
sub esp, 20h |
mov esi, esp |
@@: |
push ebx |
push ebx |
push ebx |
push esi |
call [GetMessageA] |
test eax, eax |
jz @f |
push esi |
call [TranslateMessage] |
push esi |
call [DispatchMessageA] |
jmp @b |
@@: |
add esp, 20h |
ret |
|
ListCommand: |
pop eax |
push edi |
push eax |
jmp [SendMessageA] |
|
MyWndProc: |
push edi ebx |
xor ebx, ebx |
mov edi, [esp+12] |
cmp dword [esp+16], 2 ; WM_DESTROY |
jnz @f |
push ebx |
call [PostQuitMessage] |
@@: |
cmp dword [esp+16], 219h ; WM_DEVICECHANGE |
jnz w |
cmp dword [esp+20], 8000h ; DBT_DEVICEARRIVAL |
jz @f |
cmp dword [esp+20], 8004h ; DBT_DEVICEREMOVECOMPLETE |
jnz w |
@@: |
call UpdateDrivesInfo |
w: |
cmp dword [esp+16], 203h ; WM_LBUTTONDBLCLK |
jnz @f |
push ebx |
push ebx |
push 188h ; LB_GETCURSEL |
call ListCommand |
cmp eax, -1 |
jz @f |
push n |
push eax |
push 189h ; LB_GETTEXT |
call ListCommand |
mov eax, n |
mov byte [eax+2], bl |
mov edx, [eax] |
mov [mtldr_out], dl |
mov dword [eax], '\\.\' |
mov dword [eax+4], edx |
call install |
@@: |
pop ebx edi |
pop eax |
push [OldWndProc] |
push eax |
jmp [CallWindowProcA] |
|
UpdateDrivesInfo: |
push ebx |
push ebx |
push 184h ; LB_RESETCONTENT |
call ListCommand |
|
CollectDrivesInfo: |
push esi |
call [GetLogicalDrives] |
mov esi, eax |
mov edx, a |
mov byte [edx], 'A' |
l: |
shr esi, 1 |
jnc d |
mov [edx+2], bl |
push edx |
call [GetDriveTypeA] |
; Uncomment following lines to allow hard drives |
; cmp eax, 3 ; DRIVE_FIXED |
; jz @f |
cmp eax, 2 ; DRIVE_REMOVABLE |
jnz d |
push ebx ; hTemplateFile |
push ebx ; dwFlagsAndAttributes |
push 3 ; dwCreationDisposition = OPEN_EXISTING |
push ebx ; lpSecurityAttributes |
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE |
push ebx ; dwDesiredAccess |
push a2 |
call [CreateFileA] |
cmp eax, -1 |
jz d |
push eax |
push ebx |
mov ecx, esp |
push ebx ; lpOverlapped |
push ecx ; lpBytesReturned |
push 1024 ; nOutBufferSize |
push n ; lpOutBuffer |
push ebx |
push ebx |
push 70C00h ; IOCTL_DISK_GET_MEDIA_TYPES |
push eax |
call [DeviceIoControl] |
pop ecx |
pop eax |
push ecx |
push eax |
call [CloseHandle] |
pop ecx |
jecxz @f ; not supported => OK |
cmp byte [n+8], 11 |
jnz d |
@@: |
mov eax, a |
mov ecx, n |
mov byte [eax+2], '\' |
push ecx |
push ebx ; nFileSystemNameSize |
push ebx ; lpFileSystemNameBuffer |
push ebx ; lpFileSystemFlags |
push ebx ; lpMaximumComponentLength |
push ebx ; lpVolumeSerialNumber |
push 1024 ; nVolumeNameSize |
mov edx, [eax] |
mov [ecx], edx |
mov word [ecx+3], ' [' |
add ecx, 5 |
mov byte [ecx], bl |
push ecx ; lpVolumeNameBuffer |
push eax ; lpRootPathName |
call [GetVolumeInformationA] |
pop eax |
push eax |
cmp byte [eax+5], bl |
jz nol |
@@: |
inc eax |
cmp byte [eax-1], bl |
jnz @b |
mov word [eax-1], ']' |
; jmp @f |
nol: |
mov byte [eax+3], bl |
@@: |
push ebx |
push 180h ; LB_ADDSTRING |
call ListCommand |
d: |
mov edx, a |
inc byte [edx] |
test esi, esi |
jnz l |
pop esi |
ret |
|
install: |
push ebx ; hTemplateFile |
push ebx ; dwFlagsAndAttributes |
push 3 ; dwCreationDisposition = OPEN_EXISTING |
push ebx ; lpSecurityAttributes |
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE |
push 0C0000000h ; dwDesiredAccess = GENERIC_READ|GENERIC_WRITE |
push eax |
call [CreateFileA] |
cmp eax, -1 |
jz deverre |
push esi ebp |
mov ebp, bootsect_dev |
xchg esi, eax |
push eax |
mov eax, esp |
push ebx |
push eax |
push 512 |
push ebp |
push esi |
call [ReadFile] |
test eax, eax |
jnz @f |
deverrl: |
push esi |
call [CloseHandle] |
pop eax |
pop ebp esi |
deverre: |
push 10h |
push ebx |
push deverr |
push edi |
call [MessageBoxA] |
ret |
@@: |
; make sure that this is FAT32 volume |
cmp word [ebp+0Bh], 200h ; bytes per sector |
jnz bootinv |
cmp word [ebp+0Eh], bx ; reserved sectors |
jz bootinv |
cmp byte [ebp+10h], bl ; number of FATs |
jz bootinv |
cmp word [ebp+11h], bx ; root dir entries |
jnz bootinv ; must be 0 for FAT32 |
cmp word [ebp+16h], bx ; length of one copy of FAT1x |
jnz bootinv |
cmp dword [ebp+20h], ebx ; length of one copy of FAT32 |
jz bootinv |
cmp byte [ebp+42h], ')' ; magic value |
jz @f |
bootinv: |
push 10h |
push ebx |
push nofat32 |
jmp re |
@@: |
; ok, this is really correct FAT32 volume, so start install |
; copy file mtldr_f |
push 80h |
push mtldr_out |
call [SetFileAttributesA] |
push ebx ; bFailIfExists |
push mtldr_out ; lpNewFileName |
push mtldr_in ; lpExistingFileName |
call [CopyFileA] |
test eax, eax |
jnz @f |
push 10h |
push ebx |
push mterr |
re: |
push edi |
call [MessageBoxA] |
jmp r |
@@: |
push 7 |
push mtldr_out |
call [SetFileAttributesA] |
; load bootsector |
push ebx ; hTemplateFile |
push ebx ; dwFlagsAndAttributes |
push 3 ; dwCreationDisposition = OPEN_EXISTING |
push ebx ; lpSecurityAttributes |
push 1 ; dwShareMode = FILE_SHARE_READ |
push 80000000h ; dwDesiredAccess = GENERIC_READ |
push btname |
call [CreateFileA] |
cmp eax, -1 |
jnz @f |
bterrc: |
push 40h |
push ebx |
push bterr |
jmp re |
@@: |
mov ecx, esp |
push eax |
push ebx |
push ecx |
push 512 |
push bootsect_new |
push eax |
call [ReadFile] |
pop ecx |
push eax |
push ecx |
call [CloseHandle] |
pop eax |
test eax, eax |
jz bterrc |
cmp dword [esp], 512 |
jnz bterrc |
; patch bootsector with real values |
push esi edi |
mov esi, bootsect_new |
mov edi, bootsect_dev |
movsb |
movsb |
movsb |
add esi, 57h |
add edi, 57h |
mov ecx, 200h-5Ah |
rep movsb |
pop edi esi |
; write bootsector |
push ebx |
push ebx |
push ebx |
push esi |
call [SetFilePointer] |
test eax, eax |
jnz deverrl |
mov eax, esp |
push ebx |
push eax |
push 512 |
push ebp |
push esi |
call [WriteFile] |
test eax, eax |
jz deverrl |
cmp dword [esp], 512 |
jnz deverrl |
; Patch backup copy of boot sector, ignore errors |
movzx eax, word [ebp+50] |
test eax, eax |
jz done_succ |
; sanity check: it must be in the reserved area, not in data |
cmp ax, word [ebp+14] |
jae done_succ |
shl eax, 9 |
push ebx |
push ebx |
push eax |
push esi |
call [SetFilePointer] |
cmp eax, -1 |
jz done_succ |
mov eax, esp |
push ebx |
push eax |
push 512 |
push ebp |
push esi |
call [WriteFile] |
; done! |
done_succ: |
push 40h |
push ok |
push succ |
push edi |
call [MessageBoxA] |
push ebx |
call [PostQuitMessage] |
r: |
pop eax |
push esi |
call [CloseHandle] |
pop ebp esi |
ret |
|
section '.rdata' data readable |
|
data resource from 'rsrc.res' |
end data |
|
ClassName db 'LISTBOX',0 |
WndName db 'Select drive',0 |
deverr db 'Cannot open physical device or device error (no administrator rights?)',0 |
nofat32 db 'Not FAT32 volume. Sorry, only FAT32 is supported at moment.',0 |
ok db 'Success',0 |
succ db 'Kolibri flash loader was successfully installed!',10 |
db 'Now you can copy the image kolibri.img and boot!',0 |
mterr db 'Cannot copy MTLD_F32',0 |
bterr db 'Cannot load ' |
btname db 'BOOT_F32.BIN',0 |
|
data import |
macro thunk a |
{a#_thunk:dw 0 |
db `a,0} |
dd 0,0,0, rva kernel32_name, rva kernel32_thunks |
dd 0,0,0, rva user32_name, rva user32_thunks |
dd 0,0,0, rva gdi32_name, rva gdi32_thunks |
dd 0,0,0,0,0 |
kernel32_name db 'kernel32.dll',0 |
user32_name db 'user32.dll',0 |
gdi32_name db 'gdi32.dll',0 |
kernel32_thunks: |
GetLogicalDrives dd rva GetLogicalDrives_thunk |
GetDriveTypeA dd rva GetDriveTypeA_thunk |
GetVolumeInformationA dd rva GetVolumeInformationA_thunk |
CreateFileA dd rva CreateFileA_thunk |
ReadFile dd rva ReadFile_thunk |
WriteFile dd rva WriteFile_thunk |
SetFilePointer dd rva SetFilePointer_thunk |
CloseHandle dd rva CloseHandle_thunk |
SetErrorMode dd rva SetErrorMode_thunk |
CopyFileA dd rva CopyFileA_thunk |
SetFileAttributesA dd rva SetFileAttributesA_thunk |
DeviceIoControl dd rva DeviceIoControl_thunk |
dw 0 |
thunk GetLogicalDrives |
thunk GetDriveTypeA |
thunk GetVolumeInformationA |
thunk CreateFileA |
thunk ReadFile |
thunk WriteFile |
thunk SetFilePointer |
thunk CloseHandle |
thunk SetErrorMode |
thunk CopyFileA |
thunk SetFileAttributesA |
thunk DeviceIoControl |
user32_thunks: |
CreateWindowExA dd rva CreateWindowExA_thunk |
GetMessageA dd rva GetMessageA_thunk |
TranslateMessage dd rva TranslateMessage_thunk |
DispatchMessageA dd rva DispatchMessageA_thunk |
PostQuitMessage dd rva PostQuitMessage_thunk |
CallWindowProcA dd rva CallWindowProcA_thunk |
SetWindowLongA dd rva SetWindowLongA_thunk |
SendMessageA dd rva SendMessageA_thunk |
MessageBoxA dd rva MessageBoxA_thunk |
dw 0 |
thunk CreateWindowExA |
thunk GetMessageA |
thunk TranslateMessage |
thunk DispatchMessageA |
thunk PostQuitMessage |
thunk CallWindowProcA |
thunk SetWindowLongA |
thunk SendMessageA |
thunk MessageBoxA |
gdi32_thunks: |
GetStockObject dd rva GetStockObject_thunk |
dw 0 |
thunk GetStockObject |
end data |
|
a2_src: |
db '\\.\' |
db '?:',0,0 |
db '?:\' |
db 'MTLD_F32',0 |
|
section '.data' data readable writable |
|
;a2 db '\\.\' |
;a db '?:',0,0 |
;mtldr_out db '?:\' |
;mtldr_in db 'MTLD_F32',0 |
a2 rb 4 |
a rb 4 |
mtldr_out rb 3 |
mtldr_in rb 9 |
|
align 4 |
OldWndProc dd ? |
devpath rb 1024 |
n rb 1032 |
bootsect_dev rb 512 |
bootsect_new rb 512 |