ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2

ANTICHAT — форум по информационной безопасности, OSINT и технологиям

ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию. Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club, и теперь снова доступен на новом адресе — forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
Вернуться   Форум АНТИЧАТ > Программирование_OLD > С/С++, C#, Delphi, .NET, Asm
   
 
 
Опции темы Поиск в этой теме Опции просмотра

  #11  
Старый 16.02.2007, 21:19
Cr4sh
Познающий
Регистрация: 25.08.2005
Сообщений: 57
Провел на форуме:
216363

Репутация: 76
Отправить сообщение для Cr4sh с помощью ICQ
По умолчанию

Цитата:
Cr4sh, нуууууу ))) так не прикольно ) Прикольно вручную анализировать ))
зато я больше чем уверен, что этот код будет стабильно работать на всей линейке от NT 4.0 и до Висты )
 

  #12  
Старый 30.04.2007, 20:01
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

Перенос программы в другое адресное пространство.

Был замечательный метод по инжекту кода в другую программу - вся наша программа постранично копировалась в чужое АП (адресное пространство) по тем же адресам со всеми заголовками, секциями и прочим.

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

Предлагаю модификацию: поиск наилучшего достаточного места в другом АП, копирование программы, коррекция фиксапов:

Код:
// 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 );
 

  #13  
Старый 04.05.2007, 00:52
gevara
Познающий
Регистрация: 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  
Старый 14.05.2007, 11:49
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

Способ конвертировать любые типы практически в любые другие.
К примеру если необходимо загнать в массив значение переменной типа 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
 

  #15  
Старый 14.05.2007, 12:21
sni4ok
Участник форума
Регистрация: 04.11.2006
Сообщений: 150
Провел на форуме:
1174659

Репутация: 175
Отправить сообщение для sni4ok с помощью ICQ
По умолчанию

Цитата:
Сообщение от _Great_  
Вот нашел несколько полезных советов для M$ Visual Studio.

7. Отладочные значения в различных областях памяти программы
более подробно тут
_http://www.codeguru.com/Cpp/W-P/win32/tutorials/article.php/c9535/
 

  #16  
Старый 14.05.2007, 21:49
gevara
Познающий
Регистрация: 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}
 

  #17  
Старый 14.05.2007, 22:59
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

2 gevara Ну это я просто для наглядности юзал функцию винсоковскую.
Суть была не в том как записать IP адрес, а в том, как увеличить его
 

  #18  
Старый 14.05.2007, 23:43
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

Цитата:
Сообщение от 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 - постирал несколько постов, заканчиваем офтопить
 

  #19  
Старый 20.05.2007, 15:16
Joker-jar
Постоянный
Регистрация: 11.03.2007
Сообщений: 581
Провел на форуме:
4172659

Репутация: 646


Отправить сообщение для Joker-jar с помощью ICQ
По умолчанию

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  
Старый 20.05.2007, 15:38
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

>>Шустрый метод копирования файлов. При правильной подборке размера буфера можно добиться космической скорости

вообщето апишка есть для этого
 
 





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ