Сейчас на форуме: Magister Yoda, vasilevradislav, tyns777, zombi-vadim (+3 невидимых)

 eXeL@B —› Программирование —› Помогите скопировать файл WinAPI + ASM
. 1 . 2 . >>
Посл.ответ Сообщение

Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 04 июня 2008 06:50
· Личное сообщение · #1

Имеется программа, авторан. лежит на сервере, по нажатии кнопки запускает презентацию. запускается с рабочей станции. доступ к папке с презентацией закрыт. участок кода, вызывающий ShellExecuteEx я нашёл, длина порядка 60-80 байт(там же обработчик ошибок). так вот мысль: после запуска авторана заменить в памяти этот участок на код, копирующий этот файл на рабочую станцию, затем нажать баттон и получить файл на руки. как дальше будет вести себя прога - неважно, всё равно закрывать.
Потому большая просьба: приведите пример рабочего кода, используя api, для копирования файла на asm. Если не трудно, с каментами. Заранее благодарен.




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 04 июня 2008 07:28
· Личное сообщение · #2

Разбирай файл используя IDA pro или отладчик. Рабочий .asm файл получить почти невозможно - для этого надо ооочень долго мучить прогу в IDA. Выясни как прога достаёт презентацию и напиши свой эквивалент. На крайняк попробуй воткнуть свою .dll в процесс и из неё делай patch или перехват.




Ранг: 192.7 (ветеран), 154thx
Активность: 0.070
Статус: Участник
The ONE

Создано: 04 июня 2008 07:52
· Личное сообщение · #3

Neuss
Копирование файла на асме ...
Описание
function CopyFile(lpExistingFileName, lpNewFileName: PChar; bFailIfExists: BOOL): BOOL;

Копирует файл.

Параметры:
lpExistingFileName: Строка к имени файлу источника.

lpNewFileName: Строка имени нового файла.

bFailIfExists:параметр определяет поведение функции в том случае если файл lpNewFileName уже существует. Если параметр True и файл существует, то функция терпит неудачу. В противном случае функция перезапишет файл.

Возвращаемые значения
Если успешно то не ноль.
Если функция терпит неудачу - ноль. Чтобы получить расширенную информацию об ошибке, вызовите функцию GetLastError.

Выглядит так - invoke CopyFile,addr lpExistingFileName,addr lpNewFileName,FALSE

-----
Сотрудник DHARMA




Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 04 июня 2008 12:38
· Личное сообщение · #4

TrueLies,
спасибо! теперь накидаю мелкую прогу на асме, копирующую файл, затем скомпилю, и полученный код, именно копирующий файл вставлю в прогу.
Наверное я не совсем точно пояснил вопрос, я ищу собственно код asm (push, call), так сказать скомпиленный. Но, имея функцию, думаю вечером разберусь.




Ранг: 192.7 (ветеран), 154thx
Активность: 0.070
Статус: Участник
The ONE

Создано: 04 июня 2008 12:55 · Поправил: TrueLies
· Личное сообщение · #5

Neuss
PUSH 0 ; FALSE
PUSH 00400001 ; NewFileName = ""
PUSH 00400002 ; ExistingFileName = ""
CALL CopyFileA ; вызываем CopyFileA

Соответственно по адресу 00400001 - имя нового файла, по адресу 00400002 - имя копируемого ...
Это только пример ...

-----
Сотрудник DHARMA




Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 04 июня 2008 13:39
· Личное сообщение · #6

TrueLies,
Спасибо! Спешу домой пробовать.




Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 04 июня 2008 14:36
· Личное сообщение · #7

Neuss
Neuss пишет:
скомпилю, и полученный код, именно копирующий файл вставлю в прогу.

есть вариант лучше:
напиши длл, скомпилируй её, инжекть её в процесс.
так будет проще

-----
EnJoy!





Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 04 июня 2008 15:18
· Личное сообщение · #8

Neuss пишет:
Спешу домой пробовать.


Обязательно отпиши что из этого получится.



Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 04 июня 2008 22:47 · Поправил: Neuss
· Личное сообщение · #9

Jupiter,
Дело в том, что сам exe файл лежит на сервере - изменить его там нет возможности, его только можно запустить на рабочей станции. Единственный выход - пропатчить запущенную программу в памяти раб станции. И следов меньше.

Так вот что вышло:
В Olly останавливаю прогу после нажатия кнопки (Кстати прога на Дельфи 6-7) и переписываю участок кода (что в будущем будет делаться мелкой прогой). Текст (пути к файлам) заранее заменил. Но! Конечный файл могу задать абсолютным путём, а исходный - только относительным (т.к. его точное положение на сервере неизвестно). Тут вся и проблема. Если прога попадает в подпапку - то она уже не понимает относительного адреса ("\Data\msg.asm"). Для проб написал вот такое:

.386
.model flat, stdcall
option casemap :none ; case sensitive

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
MsgBoxCaption db "Message",0
MsgBoxText db "Complete",0
SrcFile db "\msg.asm",0
DestFile db "\msg1.asm",0

.code

start:
invoke CopyFile,addr SrcFile, addr DestFile, FALSE
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK
invoke ExitProcess, NULL
end start


Окошко вылетает только для того чтобы увидеть прогу. CopyFile ошибок не возвращает, в EAX 0. В корне диска копирует. Оба файла кидаю в папку - результата нет. Как исправить ситуацию?

Вот ещё грабли... В HView 6.12 переписываю код на свой. Всё нормально в дизассемблере выглядит, но в Olly вижу следующее:
004DFFA3 . 58 POP EAX
004DFFA4 . 5B POP EBX
004DFFA5 . 6A 00 PUSH 0
004DFFA7 . 68 A8014E00 PUSH AutoRun.004E01A8 ; ASCII "C:\file.pps"
004DFFAC . 53 PUSH EBX
004DFFAD E8 DB E8
004DFFAE . D27432 00 SAL BYTE PTR DS:[EDX+ESI],CL
004DFFB2 . C3 RETN


Вместо:

004DFFA3 . 58 POP EAX
004DFFA4 . 5B POP EBX
004DFFA5 . 6A 00 PUSH 0
004DFFA7 . 68 A8014E00 PUSH AutoRun.004E01A8 ; ASCII "C:\file.pps"
004DFFAC . 53 PUSH EBX
004DFFAD E8 D268F2FF CALL <JMP.&kernel32.CopyFileA>
004DFFB2 . C3 RETN


Т.е. call не определяется Olly, вместо него данные. Повторюсь, в дизассембелере всё как во втором примере. Неясно почему:

HView пишет E8D2743200 (call 00406884)
Olly пишет E8 D268F2FF (call 00406884)

При замене кода в Olly всё отработало "на ура". Получив из программы абсолютный путь к исходному файлу, функция полностью скопировала файл на новое место. Правда в EAX было "1"... После прога выдала ошибку (что и понятно). После нажатия Ок продолжила работу. Но это уже не важно.

P.S. первые два pop'а достают из стека абсолютный адрес исходного файла. Нашёл место где сама прога его получает.



Ранг: 77.1 (постоянный)
Активность: 0.040
Статус: Участник

Создано: 05 июня 2008 00:39 · Поправил: Sh[AHT]
· Личное сообщение · #10

Neuss пишет:
то она уже не понимает относительного адреса ("\Data\msg.asm"

Это не относительный путь, а абсолютный - первый слеш указывает на корень текущего диска. Поэтому в корне диска работает, а в подпапке нет. Попробуй просто "Data\msg.asm". Ну или так ".\data\msg.asm".




Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 05 июня 2008 00:45
· Личное сообщение · #11

Neuss пишет:
Дело в том, что сам exe файл лежит на сервере - изменить его там нет возможности, его только можно запустить на рабочей станции.


и как это мешает инжекту длл в память процесса?

-----
EnJoy!




Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 05 июня 2008 05:43
· Личное сообщение · #12

Jupiter,
"В память" я пропустил, извиняюсь, теперь идея ясна. Просто я не совсем представляю как это сделать. Опыта маловато. Для меня проще переписать участок памяти - тут я в курсе дела.

Sh[AHT],
Спасибо! Снова жду вечера, буду продолжать.

Вопрос про Olly и HView остался..




Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 05 июня 2008 06:52
· Личное сообщение · #13

Neuss это от того, что ты не знаешь PE формат. Когда ты скомпилил код на асме, линкер собрал файл и получилось следующее:

Он сделал тебе таблицу импорта, в этой таблице хранятся указатели на имена функций. При загрузке указатели заменяются на абсолютные адреса функций, т.к. в каждой системе адрес одной и той же функции разный.

Где то в коде он вставил примерно такой код:
jmp dword ptr [xxxxxxxx], где xxxxxxxx адрес ячейки таблицы, где хранится адрес апи функции CopyFileA.

А код
004DFFA3 . 58 POP EAX
004DFFA4 . 5B POP EBX
004DFFA5 . 6A 00 PUSH 0
004DFFA7 . 68 A8014E00 PUSH AutoRun.004E01A8 ; ASCII "C:\file.pps"
004DFFAC . 53 PUSH EBX
004DFFAD E8 D268F2FF CALL <JMP.&kernel32.CopyFileA>
004DFFB2 . C3 RETN

CALL <JMP.&kernel32.CopyFileA> как раз и вызывает этот jmp dword ptr [xxxxxxxx].

Подведем итог. Для того чтобы CALL <JMP.&kernel32.CopyFileA> сработал нужно в программе найти jmp dword ptr [addr_of_copyfilea] и сделать так, чтобы CALL <JMP.&kernel32.CopyFileA> указывал на него.

Но! jmp dword ptr [addr_of_copyfilea] может и не быть, если программа не пользуется этой апи, тогда есть 2 варианта.

1) Вычислить адрес апи самому через GetModuleHandleA('kernel32')/GetProcAddress. Это с одной стороны не сложно, т.к. в программе, скомпиленой на Delphi ты 100% найдешь jmp dword ptr [addr_of_GetModuleHandleA] и jmp dword ptr [addr_of_GetProcAddress], но с другой стороны это достаточно сложно для новичка, т.к. нужны хотябы поверхностные знания вирусмакерства в области базонезависимого кода.

2) Если Использовать код на одной системе, то можно вписать известный адрес CopyFileA, типа так (чтобы не париться со смещениями):
push
push
push
call MyCopy
***
MyCopy:
push 77665544
retn

В любом случае импорт не такая простая штука.

-----
Yann Tiersen best and do not fuck




Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 05 июня 2008 07:14
· Личное сообщение · #14

PE_Kill,
я брал W32Dasm, в нём открыл список имортированных функций, нашёл kernel32.CopyFileA и перешёл к строке где стоит jmp на функцию. И этот адрес писал в call.
До этого "родная" ShelllExecuteA" ссылалась на похожий адрес, но уже своего jmp.
Получается что адрес api функции можно вычислить и использовать нужную функцию, даже если в норме она программой не используется?

На всякий случай, что лучше с вашей точки зрения: добавить длл или код править? по-любому должна же быть внешняя программа, добавляющая длл в прогу или пишущая свой код... и сложно ли длл добавить?

p.s. читаю msdn в поисках функции копирования директории. Только найти немогу. Выходит копировать надо через FindFirstFile и FindNextFile?




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 05 июня 2008 18:07 · Поправил: ToBad
· Личное сообщение · #15

Neuss я вот всё равно не пойму принципа. Вы правите программу которая имеет доступ к папке с нужными файлами, а пользователю доступ туда закрыт ? Таким образом любая вызываемая из тела программы функция для работы с файлами имеет доступ, а Вы нет ? Если дело в правах, то что мешает вызвать из программы через shellexecute фар, тотал или cmd.exe ? Административные права будут унаследованы... Или я чего то не понял ?

Neuss пишет:
Неясно почему:

HView пишет E8D2743200 (call 00406884)
Olly пишет E8 D268F2FF (call 00406884)


У меня была похожая проблема только с dll. Я пытался вставить код в область указанную в релоках...



Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 05 июня 2008 23:37 · Поправил: Neuss
· Личное сообщение · #16

ToBad
Выходит всё равно откуда будет запущен фар, главное кем будет запущен?

А по поводу "неправильного" call нашёл решение - надо было смещение указывать, а не адрес.

Глупый вопрос: как создать переменную с hex данными? Нашёл такой пример, но masm32 ругается
Bytes DD 50 00 00
пробовал так: выглядит отлично, но стоит добавить A8h и подобные, начинающиеся с буквы - ругается...
Bytes db 58h, 5Bh, 6Ah, 00h, 68h,

Нигде найти информацию не смог, потому прошу помощи.

p.s. Если не трудно, напишите, где можно прочитать о работе с массивами в masm32. Как создать и как обеспечить доступ к нему.




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 06 июня 2008 01:32
· Личное сообщение · #17

Neuss пишет:
Выходит всё равно откуда будет запущен фар, главное кем будет запущен?


Если я правильно понял - то да.



Ранг: 53.9 (постоянный), 19thx
Активность: 0.040
Статус: Участник

Создано: 06 июня 2008 04:16
· Личное сообщение · #18

Neuss пишет:
Глупый вопрос: как создать переменную с hex данными? Нашёл такой пример, но masm32 ругается
Bytes DD 50 00 00
пробовал так: выглядит отлично, но стоит добавить A8h и подобные, начинающиеся с буквы - ругается...
Bytes db 58h, 5Bh, 6Ah, 00h, 68h,

Попробуй 0 добавить перед буквой



Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 06 июня 2008 06:36
· Личное сообщение · #19

ToBad
Спасибо за идею, напишу 2 патча. Один просто выкачает файл, другой запускаь ФАР будет, попробую, отпишусь когда проверю на сервере.

Zorn
Спасибо! Помогло.




Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 06 июня 2008 07:57
· Личное сообщение · #20

Neuss пишет:
Получается что адрес api функции можно вычислить и использовать нужную функцию, даже если в норме она программой не используется?

Да, конечно. А как по твоему вирусы в телах программах живут? Они вообще понятия не имют какие функции программа использует.

-----
Yann Tiersen best and do not fuck





Ранг: 192.7 (ветеран), 154thx
Активность: 0.070
Статус: Участник
The ONE

Создано: 06 июня 2008 09:54 · Поправил: TrueLies
· Личное сообщение · #21

Neuss пишет:
Получается что адрес api функции можно вычислить и использовать нужную функцию, даже если в норме она программой не используется?

--> Вот <-- http://www.zshare.net/download/131944779c5bd073/ пример экзешника (+ исходник) вообще без импорта, все апи он вычисляет сам ... пример из пакета masm.

-----
Сотрудник DHARMA




Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 07 июня 2008 22:30
· Личное сообщение · #22

Дело продолжается... Патчер меняющий код для выкачивания конкретного файла уже есть и работает, проверен в условиях домашней сети двух компов.

В процессе переписывания кода для запуска TotalCommander встретил новую проблему: необходимо записать данные в память (переменную). Оказалось что любое место в проге не пожходит для этих целей...

004DFFAA . A3 F0FF4000 MOV DWORD PTR DS:[40FFF0],EAX ; AutoRun.00400000

Выдаёт ошибку записи в память. Если не трудно, объясните в двух словах от чего это? и где в норме выделяется память для переменных(как найти её у конкретной программы)?




Ранг: 238.8 (наставник), 67thx
Активность: 0.20
Статус: Участник
CyberHunter

Создано: 08 июня 2008 00:06
· Личное сообщение · #23

MOV DWORD PTR DS:[40FFF0],EAX

Возможно, по адресу находится область памяти в которую нет прав на запись (секция кода например), чтобы записать нужно сначала заюзать api функцию VirtualProtect

push x ;pOldProtect, куда сохраним старые права доступа
push 4 ;NewProtect, это новые, 4 значит на чтение/запись
push y ;Size размер памяти
push 40FFF0 ; Address начало памяти
Call VirtualProtect

-----
Nulla aetas ad discendum sera





Ранг: 467.7 (мудрец), 5thx
Активность: 0.270
Статус: Участник
Иной :)

Создано: 08 июня 2008 02:15
· Личное сообщение · #24

Я что то не догоняю или тут какая то магия... Есть возможность запустить бинарник с удаленого компа, но нет возможности скопировать его оттуда? Что за ахинея? Чтобы файл запустился на локальной машине он должен будет скачаться на локальную машину так или иначе. Хрен с ним поверю что нельзя скопировать стандартными срествами винды, но что мешает сдампить файл? Или опять волшебство мелкософта?

Файлы не стартуют от имени владельца файла. Они стартую от имени пользователя который запускает файл. Запущеный процесс может пораждать процессы и они унаследуют права этого пользователя, но никоем образом права повыситься не могут. Так что если прога читает файлы значит права у пользователя на чтение есть 100% !!! Другое дело что на листинг/обзор папки прав может небыть и тогда только нужно знать имена файлов чтобы скопировать/прочесть их.

Я понимаю что метод с инжектами и правкой кода на лету это метод интересный, но помоему это тоже самое что вырезать гланды через толстую кишку.

-----
Computer Security Laboratory




Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 08 июня 2008 07:51
· Личное сообщение · #25

[HEX],
Возможность взять бинарник есть и он взят. Во нужен не он. Пример: На сервере есть папка Program - доступ только чтение, в ней подпапка Data - чтение запрещено.
Есть прога авторан - по нажатии кнопки запускает искомую прогу из папки Data, сама находится в Program.
Очевидно же, если прога может запустить оттуда файл, значит может и скопировать. Просто зайти через проводник и подобные в Data нельзя, от того и нужен патч.

[Flint],
Спасибо!




Ранг: 467.7 (мудрец), 5thx
Активность: 0.270
Статус: Участник
Иной :)

Создано: 08 июня 2008 13:34 · Поправил: [HEX]
· Личное сообщение · #26

Neuss
В папку Data не можешь зайти и скопировать её не можешь? Но прога читает оттуда файлы? Значит на папке стоит запрет на просмотр содержимого, но читать файлы ты можешь! Тебе только нужно знать имена файлов в этой папке (наверное в проге авторане прописаны все имена файлов).

http://img257.imageshack.us/my.php?image=folderbh0.jpg

Чтобы не заморачиваться со всякой отладкой и просмотром байтиков думаю будет достаточно посмотреть открытые или открываемые файлы во время запуска проги. Например с помощью Process Monitor от Sysinternals. Получишь полный путь до файла в папке Data. Ну а потом в том же фаре можно скопировать будет ручками.

-----
Computer Security Laboratory





Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 09 июня 2008 02:58 · Поправил: Jupiter
· Личное сообщение · #27

чтобы скопировать файл, не заходя в каталог, создай bat/cmd файл для копирования файла:


@echo off
Set SourcePath=путь до папки дата, в которой лежит файл
Set DestPath=локальный путь
Set SourceFile=файл в папке дата (см. пост [HEX] про то, как получить имя файла)
Set DestFile=имя файла для сохранения локально, можешь выставить в %SourceFile%

@echo Copy file %SourceFile% from %SourcePath% to %DestPath%...
copy /B %SourcePath%%SourceFile% %DestPath%%DestFile%


-----
EnJoy!




Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 09 июня 2008 06:46 · Поправил: Neuss
· Личное сообщение · #28

Спасибо за множество оригинальных идей!
Дело вот в чём: мне известно что за файл и где он лежит. Уже есть патч на asm'е заставляющий авторан копировать требуемый файл в локальную папку.
Однако рядом с папкой есть ещё много чего интересного.. Есть ли возможность того что прога (авторан) запущенная с сервера сможет найти все файлы (getfirstfile getnextfile) и по-очереди скопировать их? думаю для пробы надо написать.
Так же уже есть возможность запуска TotalCommander, как советовали. Может быть права на доступ передадутся от авторана. В ShellExecuteA hWnd окна, запустившего, передаётся.

Вопрос:
команда

mov eax, dword ptr[ebx+0C]

в еах помещает данные из памяти по адресу в ebx длиной в OCh?

возможна ли запись:

mov eax, dword ptr[004DFFA8+0C]

При изменении "OCh" будет меняться длина загружаемой строки? И какова альтернатива при написании asm файла?
mov Variable1, eax - тут полностью перенесётся, а как урезать строку?




Ранг: 238.8 (наставник), 67thx
Активность: 0.20
Статус: Участник
CyberHunter

Создано: 09 июня 2008 08:17
· Личное сообщение · #29

Neuss пишет:
команда mov eax, dword ptr[ebx+0C]
в еах помещает данные из памяти по адресу в ebx длиной в OCh?


нет, в eax помещается 4 байта расположенные по адресу [ebx +0c], см. чему равен ebx, к примеру ebx = 00401000, тогда команда mov eax, dword ptr[ebx+0C], положит в eax данные (4 байта) которые расположены по адресу 0040100С.


Neuss пишет:
возможна ли запись:
mov eax, dword ptr[004DFFA8+0C]


конечно возможна

-----
Nulla aetas ad discendum sera




Ранг: 12.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 09 июня 2008 10:24
· Личное сообщение · #30

Тогда так:
по адресу 00403000 лежит строка "C:\Program files\Program" - всего 18h байт - переменная Path
требуется её укоротить до длины 10h - "C:\Program files" - т.е. либо указать ассемблеру что длина переменной сократилась, либо заново считать в переменную только 10h символов, начиная с того же адреса.

Как это будет выглядеть в asm файле?


. 1 . 2 . >>
 eXeL@B —› Программирование —› Помогите скопировать файл WinAPI + ASM
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати