ANTICHAT — форум по информационной безопасности, OSINT и технологиям
ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию.
Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club,
и теперь снова доступен на новом адресе —
forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.

16.02.2007, 21:19
|
|
Познающий
Регистрация: 25.08.2005
Сообщений: 57
Провел на форуме: 216363
Репутация:
76
|
|
Cr4sh, нуууууу ))) так не прикольно ) Прикольно вручную анализировать ))
зато я больше чем уверен, что этот код будет стабильно работать на всей линейке от NT 4.0 и до Висты  )
|
|
|

30.04.2007, 20:01
|
|
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме: 5339610
Репутация:
4360
|
|
Перенос программы в другое адресное пространство.
Был замечательный метод по инжекту кода в другую программу - вся наша программа постранично копировалась в чужое АП (адресное пространство) по тем же адресам со всеми заголовками, секциями и прочим.
Все было бы хорошо, пока там память свободна. Если там память занята, метод не предусматривал решения в этом случае.
Предлагаю модификацию: поиск наилучшего достаточного места в другом АП, копирование программы, коррекция фиксапов:
Код:
// Get VA
#define RVATOVA( base, offset )(((DWORD)(base) + (DWORD)(offset)))
// Move program's memory
void __CopyMemoryAcrossProcesses( HANDLE hProcess, char* pMemLocal, char* pMemRemote )
{
DWORD dwOldProt, dwNumBytes, i;
MEMORY_BASIC_INFORMATION mbi;
VirtualQueryEx(hProcess, pMemRemote, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
while (mbi.Protect!=PAGE_NOACCESS && mbi.RegionSize!=0)
{
if (!(mbi.Protect & PAGE_GUARD))
{
for (i = 0; i < mbi.RegionSize; i += 0x1000)
{
VirtualProtectEx(hProcess, pMemRemote + i, 0x1000,PAGE_EXECUTE_READWRITE, &dwOldProt);
WriteProcessMemory(hProcess, pMemRemote + i, pMemLocal + i, 0x1000, &dwNumBytes);
}
}
pMemLocal += mbi.RegionSize;
pMemRemote += mbi.RegionSize;
VirtualQueryEx(hProcess, pMemRemote, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
}
}
bool TransferProgram(HANDLE hProcess)
{
HMODULE g_module = GetModuleHandle(0);
VirtualFreeEx(hProcess, g_module, 0, MEM_RELEASE);
DWORD dwSize = ((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE *)(g_module) + ((PIMAGE_DOS_HEADER)(g_module))->e_lfanew +
sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER))))->SizeOfImage;
char *pMem = (char *)VirtualAllocEx(hProcess, g_module, dwSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(pMem == NULL) return FALSE;
__CopyMemoryAcrossProcesses( hProcess, (char*) g_module, pMem );
return true;
}
DWORD TransferProgramEx(HANDLE hProcess)
/*
Return value: image base delta, -1 on error
*/
{
HMODULE hmodule = GetModuleHandle(0);
DWORD dwSize = ((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE *)(hmodule) + ((PIMAGE_DOS_HEADER)(hmodule))->e_lfanew +
sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER))))->SizeOfImage;
MEMORY_BASIC_INFORMATION mbi = {0};
VirtualQueryEx( hProcess, hmodule, &mbi, sizeof(mbi) );
LPVOID Allocated;
// Memory isn't free, relocate
if( mbi.Protect!=PAGE_NOACCESS && mbi.RegionSize!=0 )
{
__try_relocate:
LPVOID DesiredAddress = hmodule;
*(DWORD*)&DesiredAddress += mbi.RegionSize;
for(;;)
{
Allocated = VirtualAllocEx( hProcess, DesiredAddress, dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if( Allocated )
break;
*(DWORD*)&DesiredAddress += dwSize;
}
}
else
{
Allocated = VirtualAllocEx( hProcess, hmodule, dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if( !Allocated )
goto __try_relocate;
}
// move memory
__CopyMemoryAcrossProcesses( hProcess, (char*) hmodule, (char*) Allocated );
DWORD ImageBaseDelta = (DWORD)Allocated - (DWORD)hmodule;
// Nonzero imagebase delta
if( ImageBaseDelta )
{
// Apply fixups
typedef struct
{
WORD Offset:12;
WORD Type:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
PIMAGE_OPTIONAL_HEADER poh =
(PIMAGE_OPTIONAL_HEADER)(
(DWORD)hmodule
+ ((PIMAGE_DOS_HEADER)hmodule)->e_lfanew
+ sizeof(IMAGE_NT_SIGNATURE)
+ sizeof(IMAGE_FILE_HEADER)
);
// No fixups?
if( !poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress )
{
VirtualFreeEx( hProcess, Allocated, dwSize, MEM_DECOMMIT );
VirtualFreeEx( hProcess, Allocated, dwSize, MEM_RELEASE );
return -1;
}
PIMAGE_BASE_RELOCATION Reloc = (PIMAGE_BASE_RELOCATION) RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, hmodule);
int i = 0;
// Process fixups
for( PIMAGE_FIXUP_ENTRY Fixup = (PIMAGE_FIXUP_ENTRY)( (DWORD)Reloc + sizeof(IMAGE_BASE_RELOCATION) );
(DWORD)Fixup < (DWORD)Reloc + Reloc->SizeOfBlock -2;
Fixup ++, i ++
)
{
if( Fixup->Type == IMAGE_REL_BASED_HIGHLOW )
{
DWORD* Patch = (DWORD*)RVATOVA( Reloc->VirtualAddress + Fixup->Offset, Allocated );
DWORD t, r;
BOOL b = 1;
// correct fixup
b &= ReadProcessMemory( hProcess, Patch, &t, 4, &r );
t += ImageBaseDelta;
b &= WriteProcessMemory( hProcess, Patch, &t, 4, &r );
if( !b )
{
// smth wrong
VirtualFreeEx( hProcess, Allocated, dwSize, MEM_DECOMMIT );
VirtualFreeEx( hProcess, Allocated, dwSize, MEM_RELEASE );
return -1;
}
}
else
{
// unsupported fixup type
VirtualFreeEx( hProcess, Allocated, dwSize, MEM_DECOMMIT );
VirtualFreeEx( hProcess, Allocated, dwSize, MEM_RELEASE );
return -1;
}
}
}
return ImageBaseDelta;
}
TransferProgram - старый вариант
TransferProgramEx - моя модификация
Использовать примерно так:
Код:
DWORD ImageBaseDelta = TransferProgramEx( hProcess );
switch(ImageBaseDelta)
{
case -1:
return printf("Cannot copy body\n"), 0;
case 0:
printf("Program copied at the same addresses\n");
break;
default:
printf("Program relocated (delta = 0x%08x)\n", ImageBaseDelta);
break;
}
DWORD thID;
HANDLE hTh;
hTh = CreateRemoteThread( hProcess, 0, 0, (LPTHREAD_START_ROUTINE)((char*)RemoteThread+ImageBaseDelta), 0, 0, &thID);
WaitForSingleObject( hTh, INFINITE );
|
|
|

04.05.2007, 00:52
|
|
Познающий
Регистрация: 30.11.2006
Сообщений: 49
Провел на форуме: 36434
Репутация:
28
|
|
_Great_
Вообще для бряка я создаю макрос
#define __INT3 __asm int 3;
более наглядней.
Удобно при написании дров использовать Int 3 причём с опкодом CC, а не с CD 03. тем более что некоторые ядерные отладчики имеют функцию: заменить все int3 (0xCC) на nop (0x90). НО ,как я понимаю, в VC такой возможности нет. обидно.
------------------------------------------------------------------------
Иногда функция должна возвращать результат своей работы (допустим ошибку), который нужно показать юзеру. Удобно делать следующим образом:
PCHAR func(...)
{
..
return "ERROR";
...
return "STATUS_SUCCESS";
}
------------------------------------------------------------------------
Что касается сишных функций - тож можно передавать параметры через регистры. достаточно при объявлении указать __fastcall :
DWORD __fastcall func1(arg1,arg2,...)
{
...
}
------------------------------------------------------------------------
Допустим, необходимо проверить 4 символа в строке.
PCHAR str1;
ULONG i;
...
if ( (str[i] == 'd') && (str[i+1]== 'c') &&...) ...
НО лучше так:
if ( *(PDWORD)&str1[i] == 'abcd' ) ...
только нужно учитывать, что компилятор переворачивает символы в строке.
|
|
|

14.05.2007, 11:49
|
|
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме: 3288241
Репутация:
3349
|
|
Способ конвертировать любые типы практически в любые другие.
К примеру если необходимо загнать в массив значение переменной типа dword, но в том формате в котором она хранится в оперативе (т.е. 4 байта).
Код:
type
massiv=array[0..3] of byte; // тип массива для хранения
DW2MAS = ^massiv;
procedure TForm1.Button1Click(Sender: TObject);
var
mas:massiv; // наш массив
d:dword; // наша Dword переменная
begin
d:=$12345678;
mas:=DW2MAS(@d)^;
//теперь содержимое массива будет таким: $78,$56,$34,$12
end;
такимже образом можно окнвертировать и другие типы. Главное чтобы из размер был одинаков. т.е. Dword - некогда не засунуть в array[0..1] of byte;
Кстати, такимже образом можно и наоборот. засовывать массив из 4-х байт в dword
Этот метод хорошь тем что работа идет напрямую с память, без использования каких либо дополнительный вычислений.
-----------------
При работе с IP адресами многие видели, что они храняться в озу в прямом порядку, т.е. старший байт на старшем месте. т.е. IP - 127.0.0.1 бедет храниться 7F000001
Это очень не удобно для увелицения значения IP адреса. т.е. к примеру появилась необходимость пройтись по диапазону 192.168.2.1 - 192.168.2.128. Сложность заключается в том что при увеличении значения на 1 будет увеличиваться старшая часть IP адреса, а не младшая (как это нам нужно).
Для этих целей пожно использовать простой метод основанный на инструкции МП - bswap которая меняет порядок байт.
Код:
function incIP(d:dword):dword;assembler;
asm
bswap eax // поменять поряд байт
inc eax // увеличить на 1
bswap eax // поменять обратно
end;
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
var
ca:sockaddr_in;
d:dword;
begin
d:=inet_addr('127.0.0.1'); // сохраним IP адресс
d:=incIP(d); // увеличим на 1
d:=incIP(d); // увеличим на 1
d:=incIP(d); // увеличим на 1
ca.sin_addr.s_addr:=d; // запишем в структуру.
end;
Тем самым в ca.sin_addr.s_addr будет число которое будет соотвествовать IP - 127.0.0.4
|
|
|

14.05.2007, 12:21
|
|
Участник форума
Регистрация: 04.11.2006
Сообщений: 150
Провел на форуме: 1174659
Репутация:
175
|
|
Сообщение от _Great_
Вот нашел несколько полезных советов для M$ Visual Studio.
7. Отладочные значения в различных областях памяти программы
более подробно тут
_http://www.codeguru.com/Cpp/W-P/win32/tutorials/article.php/c9535/
|
|
|

14.05.2007, 21:49
|
|
Познающий
Регистрация: 30.11.2006
Сообщений: 49
Провел на форуме: 36434
Репутация:
28
|
|
Ещё не понимаю код типа:
d=inet_addr('127.0.0.1');
здесь логичней присваивать значение напрямую: d=0x0100007F;
хотя, это не так наглядно, но ведь можно
d=0x0100007F; // 127.0.0.1
тоже самое с инициализацией портов, юникод строк:
#define InitUnicodeString(string) {sizeof(string)-2,sizeof(string),string}
|
|
|

14.05.2007, 22:59
|
|
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме: 3288241
Репутация:
3349
|
|
2 gevara Ну это я просто для наглядности юзал функцию винсоковскую.
Суть была не в том как записать IP адрес, а в том, как увеличить его 
|
|
|

14.05.2007, 23:43
|
|
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме: 5339610
Репутация:
4360
|
|
Сообщение от gevara
_Great_
Вообще для бряка я создаю макрос
#define __INT3 __asm int 3;
более наглядней.
Удобно при написании дров использовать Int 3 причём с опкодом CC, а не с CD 03. тем более что некоторые ядерные отладчики имеют функцию: заменить все int3 (0xCC) на nop (0x90). НО ,как я понимаю, в VC такой возможности нет. обидно.
Вообще-то, __asm int 3 геренит CC, а не CD 03.
Команда CD 03 отнюдь не аналогична CC и таких "отладочных" свойств, насколько я помню, не имеет.
CC - Это НЕ просто однобайтовая замена для CD 03.
Поэтому __asm int 3 генерит сразу CC, а чтобы сгенерить CD 03 надо явно написать
__asm emit 0xCD
__asm emit 0x03
2all - постирал несколько постов, заканчиваем офтопить
|
|
|

20.05.2007, 15:16
|
|
Постоянный
Регистрация: 11.03.2007
Сообщений: 581
Провел на форуме: 4172659
Репутация:
646
|
|
Delphi.
Функция округления числа до нужного количества знаков:
Код:
function RoundFloat(R: Extended; Decimals: Integer): Extended;
var
Factor: Extended;
begin
Factor := Int(Exp(Decimals * Ln(10)));
Result := Round(Factor * R) / Factor;
end;
Используя вышеописанную функцию, получаем окгугленный размер файла в килобайтах (наиболее универсальная величина для большинства файлов):
Код:
Function FileSizeInKb(YourFile : String) : string;
Var
arg: extended;
F : Integer;
Begin
F:=FileOpen(YourFile,0);
arg := FileSeek(F,0,2);
FileClose(F);
arg:=roundfloat(arg/1024,1);
result:=floattostr(arg);
End;
Функция проверяет, открыт ли порт на хосте, с указанием времени ожидания ответа. Отличная вещь для написания сканера одного порта на диапазоне адресов. Зависимость - winsock2, обертку под делфню можно найти хде угодно
Код:
function PingPort(host: string; portnum: word; tim: integer): boolean;
var
k: integer;
s, opt: Integer;
FSocket: TSOCKET;
busy : boolean;
addr : TSockAddr;
hEvent : THandle;
fset : TFDset;
tv : TTimeval;
tec :PServEnt;
PName:String;
GInitData : TWSADATA;
begin
result := false;
WSAStartup(MAKEWORD(2,0), GInitData);
addr.sin_family := AF_INET;
addr.sin_addr.s_addr := INADDR_ANY;
addr.sin_port := htons(portnum);
hEvent := WSACreateEvent();
busy:=false;
FSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
WSAEventSelect(FSocket, hEvent, FD_WRITE + FD_CONNECT);
addr.sin_addr := LookupName(host);
connect(FSocket, @addr, sizeof(addr));
if WSAGetLastError()=WSAEINPROGRESS then
begin
closesocket (FSocket);
busy:=true;
end;
FD_Zero(fset);
if busy <> true then
FD_SET (FSocket, fset);
tv.tv_sec := tim;
tv.tv_usec := 0;
s:=select (1, nil, @fset, nil, @tv);
if busy then
exit;
if FD_ISSET (FSocket, fset) then
begin
s:=Sizeof(Opt);
opt:=1;
getsockopt(FSocket, SOL_SOCKET, SO_ERROR, @opt, s);
if opt=0 then
result := true;
closesocket(FSocket);
end;
WSACloseEvent(hEvent);
WSACleanup;
end;
Шустрый метод копирования файлов. При правильной подборке размера буфера можно добиться космической скорости
Код:
procedure CopyFile(file1,file2: string);
var
FromF, ToF: file;
NumRead, NumWritten: Integer;
Buf: array[1..2048] of Char;
begin
AssignFile(FromF, file1);
Reset(FromF, 1);
AssignFile(ToF, File2);
Rewrite(ToF, 1);
repeat
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
BlockWrite(ToF, Buf, NumRead, NumWritten);
until
(NumRead = 0) or (NumWritten <> NumRead);
CloseFile(FromF);
CloseFile(ToF);
end;
|
|
|

20.05.2007, 15:38
|
|
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме: 5339610
Репутация:
4360
|
|
>>Шустрый метод копирования файлов. При правильной подборке размера буфера можно добиться космической скорости
вообщето апишка есть для этого
|
|
|
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|