Как стать автором
Обновить

Комментарии 18

Было бы здорово вкратце про механизм проверки подписи, etc.

PS:
Невероятно, но systracer мог и сам написать пост, сообщите ему об этой приятной возможности. ;-)
Описание механизма проверки очень легко найти поисковиком, например здесь — эта информация вообще не дефицит.

P. S. Раньше не мог написать пост, кое-чего не хватало.
>А такой утилиты официально нет.
Так надо такую утилиту срочно официально написать! )
По материалу статьи, Crystall написал утилиту, удаляющую цифровую подпись:
dl.dropbox.com/u/11919847/de.sign.exe (исходники: dl.dropbox.com/u/11919847/de.sign.rar).
Связаться с ним для обсуждения и инвайта можно по ICQ:558113633.
«Если нужно изменить подписанный файл, например исправить в нём ошибки или локализовать.» — или сделать crack, господи прости… :-)
Статья — хороша. Не каждый разбирается в таких вещах.
То, что я хотел читать на Хабре ) Отличный пост )
>Последующие два значения относятся непосредственно к цифровой подписи. Если они состоят из нулей — подписи нет.
последующие два занчения за полем CheckSum это поля Subsystem и DllCharacteristics.
вариант по удалению подписи еще проще:
-качаем CFF Explorer
-открываем в нем наш exe
— далее в Data Directories находим Security Directory и удаляем
Спасибо за замечание, имелись в виду нужные нам поля. CFF Explorer просто заполняет их нулями — это тоже допустимо, но тогда останется хвост из подписи, в данном случае лишних 5376 байт.
байты не переворачиваются, это little-endian
Имелось в виду следующее: если читать слева направо или выделять и копировать, то чтобы посчитать числа в обычном калькуляторе их нужно переворачивать.
Половина указанных операций в Hiew делается автоматически, например очистка директории и изменение контрольной суммы.
неплохо бы и саму утилиту написать :)
Конечно, такое объяснение весьма ценно и само по себе, но слегка трудоёмко, если делать часто.
На хабре снова появились торты.
Я так стану сладкоежкой.
Прилагаю свой код для нахождения полного размера PE образа. В случае, если полученное значение (возвращается через переданный в параметре image_size указатель) не совпадает (меньше) с размером EXE/DLL/SYS файла — значит начиная с данного смещения в файле следует цифровая подпись или иные данные.
Определения структур _IMAGE_* и констант есть в winnt.h (составляющая часть windows.h), включены просто для удобства и портабельности.

#include <stdio.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;

#define IMAGE_DOS_SIGNATURE 0x5A4D
#define IMAGE_NT_SIGNATURE 0x4550
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4

typedef struct _IMAGE_DOS_HEADER {
	WORD e_magic;
	WORD e_cblp;
	WORD e_cp;
	WORD e_crlc;
	WORD e_cparhdr;
	WORD e_minalloc;
	WORD e_maxalloc;
	WORD e_ss;
	WORD e_sp;
	WORD e_csum;
	WORD e_ip;
	WORD e_cs;
	WORD e_lfarlc;
	WORD e_ovno;
	WORD e_res[4];
	WORD e_oemid;
	WORD e_oeminfo;
	WORD e_res2[10];
	LONG e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef struct _IMAGE_FILE_HEADER {
	WORD Machine;
	WORD NumberOfSections;
	DWORD TimeDateStamp;
	DWORD PointerToSymbolTable;
	DWORD NumberOfSymbols;
	WORD SizeOfOptionalHeader;
	WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

typedef struct _IMAGE_DATA_DIRECTORY {
	DWORD VirtualAddress;
	DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

typedef struct _IMAGE_OPTIONAL_HEADER {
	WORD Magic;
	BYTE MajorLinkerVersion;
	BYTE MinorLinkerVersion;
	DWORD SizeOfCode;
	DWORD SizeOfInitializedData;
	DWORD SizeOfUninitializedData;
	DWORD AddressOfEntryPoint;
	DWORD BaseOfCode;
	DWORD BaseOfData;
	DWORD ImageBase;
	DWORD SectionAlignment;
	DWORD FileAlignment;
	WORD MajorOperatingSystemVersion;
	WORD MinorOperatingSystemVersion;
	WORD MajorImageVersion;
	WORD MinorImageVersion;
	WORD MajorSubsystemVersion;
	WORD MinorSubsystemVersion;
	DWORD Win32VersionValue;
	DWORD SizeOfImage;
	DWORD SizeOfHeaders;
	DWORD CheckSum;
	WORD Subsystem;
	WORD DllCharacteristics;
	DWORD SizeOfStackReserve;
	DWORD SizeOfStackCommit;
	DWORD SizeOfHeapReserve;
	DWORD SizeOfHeapCommit;
	DWORD LoaderFlags;
	DWORD NumberOfRvaAndSizes;
	IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;

typedef struct _IMAGE_NT_HEADERS {
	DWORD Signature;
	IMAGE_FILE_HEADER FileHeader;
	IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;

typedef IMAGE_NT_HEADERS IMAGE_NT_HEADERS32;

typedef struct _IMAGE_SECTION_HEADER {
	BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
	union {
		DWORD PhysicalAddress;
		DWORD VirtualSize;
	} Misc;
	DWORD VirtualAddress;
	DWORD SizeOfRawData;
	DWORD PointerToRawData;
	DWORD PointerToRelocations;
	DWORD PointerToLinenumbers;
	WORD NumberOfRelocations;
	WORD NumberOfLinenumbers;
	DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

int GetPESize(FILE *fEXE, DWORD *image_size, DWORD *sd_addr, DWORD *sd_size)
{
	BYTE buff[4096];
	if (fread(buff, sizeof(buff), 1, fEXE) != 1)
		return 1;
	IMAGE_DOS_HEADER *dosheader = (IMAGE_DOS_HEADER *) buff;
	IMAGE_NT_HEADERS32 *pe_header = (IMAGE_NT_HEADERS32 *)(buff + dosheader->e_lfanew);
	if (dosheader->e_magic != IMAGE_DOS_SIGNATURE || pe_header->Signature != IMAGE_NT_SIGNATURE)
		return 1;
	IMAGE_SECTION_HEADER *sectiontable = (IMAGE_SECTION_HEADER *)((BYTE *) pe_header + sizeof(IMAGE_NT_HEADERS32));
	DWORD maxpointer = 0, exesize = 0;
	unsigned int i;
	for (i = 0; i < pe_header->FileHeader.NumberOfSections; i++)
	{
		if (sectiontable->PointerToRawData > maxpointer)
		{
			maxpointer = sectiontable->PointerToRawData;
			exesize = sectiontable->PointerToRawData + sectiontable->SizeOfRawData;
		}
		sectiontable++;
	}
	*image_size = exesize;
	IMAGE_DATA_DIRECTORY *sd = &pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
	*sd_addr = sd->VirtualAddress;
	*sd_size = sd->Size;
	return 0;
}
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации