示例#1
0
文件: pesteg.c 项目: weslleymberg/pev
bool find_section(PE_FILE *pe, IMAGE_SECTION_HEADER *sec, bool executable)
{
	rewind(pe->handle);
	if (!pe_get_sections(pe))
		return false;

	if (fseek(pe->handle, pe->addr_sections, SEEK_SET))
		return false;

	for (unsigned int i=0; i < pe->num_sections; i++)
	{
		fread(sec, sizeof(*sec), 1, pe->handle);
		if (executable && (sec->Characteristics & 0x20))
			return true;
	}
	return false;
}
示例#2
0
static void print_strange_sections(PE_FILE *pe)
{
	bool aux = false;

	if (!pe_get_sections(pe) || !pe->num_sections)
		return;

	if (pe->num_sections <= 2)
		snprintf(value, MAX_MSG, "%d (low)", pe->num_sections);
	else if (pe->num_sections > 8)
		snprintf(value, MAX_MSG, "%d (high)", pe->num_sections);
	else
		snprintf(value, MAX_MSG, "%d", pe->num_sections);

	output("section count", value);
	for (unsigned i=0; i < pe->num_sections && i <= 65535; i++, aux=false)
	{
		memset(&value, 0, sizeof(value));

		if (!strisprint((const char *)pe->sections_ptr[i]->Name))
			stradd(value, "suspicious name", &aux);

		if (!pe->sections_ptr[i]->SizeOfRawData)
			stradd(value, "zero length", &aux);
		else if (pe->sections_ptr[i]->SizeOfRawData <= 512)
			stradd(value, "small length", &aux);

		// rwx or writable + executable code
		if (pe->sections_ptr[i]->Characteristics & 0x80000000 &&
		(pe->sections_ptr[i]->Characteristics & 0x20 ||
		pe->sections_ptr[i]->Characteristics & 0x20000000))
			stradd(value, "self-modifying", &aux);

		if (!aux)
			strncpy(value, "normal", 7);

		output((char *)pe->sections_ptr[i]->Name, value);
	}
}
示例#3
0
static IMAGE_SECTION_HEADER *pe_check_fake_entrypoint(PE_FILE *pe, DWORD *ep)
{
	IMAGE_SECTION_HEADER *epsec = NULL;

	if (!pe->optional_ptr)
		pe_get_optional(pe);

	if (!pe->num_sections || !pe->sections_ptr)
		pe_get_sections(pe);

	if (!pe->num_sections)
		return NULL;

	epsec = pe_rva2section(pe, *ep);

	if (!epsec)
		return NULL;

	if (!(epsec->Characteristics & 0x20))
		return epsec;

   return NULL;
}
示例#4
0
/*
 * -1 - fake tls callbacks detected
 *  0 - no tls directory
 * >0 - number of callbacks functions found
*/
static int pe_get_tls_callbacks(PE_FILE *pe)
{
	QWORD tls_addr = 0;
	int ret = 0;

	if (!pe)
		return 0;

	tls_addr = pe_get_tls_directory(pe);

	if (!tls_addr || !pe_get_sections(pe))
		return 0;


	// search for tls in all sections
	for (unsigned int i=0, j=0; i < pe->num_sections; i++)
	{
		if (tls_addr >= pe->sections_ptr[i]->VirtualAddress &&
		tls_addr < (pe->sections_ptr[i]->VirtualAddress + pe->sections_ptr[i]->SizeOfRawData))
		{
			unsigned int funcaddr = 0;

			if (fseek(pe->handle, tls_addr - pe->sections_ptr[i]->VirtualAddress
			+ pe->sections_ptr[i]->PointerToRawData, SEEK_SET))
			 	return 0;

			if (pe->architecture == PE32)
			{
				IMAGE_TLS_DIRECTORY32 tlsdir32;

				if (!fread(&tlsdir32, sizeof(tlsdir32), 1, pe->handle))
					return 0;

				if (! (tlsdir32.AddressOfCallBacks & pe->optional_ptr->_32->ImageBase))
					break;

				if (fseek(pe->handle,
						rva2ofs(pe, tlsdir32.AddressOfCallBacks - pe->optional_ptr->_32->ImageBase), SEEK_SET))
					return 0;
			}
			else if (pe->architecture == PE64)
			{
				IMAGE_TLS_DIRECTORY64 tlsdir64;

				if (!fread(&tlsdir64, sizeof(tlsdir64), 1, pe->handle))
					return 0;

				if (! (tlsdir64.AddressOfCallBacks & pe->optional_ptr->_64->ImageBase))
					break;

				if (fseek(pe->handle,
				 rva2ofs(pe, tlsdir64.AddressOfCallBacks - pe->optional_ptr->_64->ImageBase), SEEK_SET))
					return 0;
			}
			else
				return 0;

			ret = -1; // tls directory and section exists
			do
			{
				fread(&funcaddr, sizeof(int), 1, pe->handle);
				if (funcaddr)
				{
					char value[MAX_MSG];

					ret = ++j; // function found

					if (config.verbose)
					{
						snprintf(value, MAX_MSG, "%#x", funcaddr);
						output("TLS callback function", value);
					}
				}
			} while (funcaddr);

			return ret;
		}
	}
	return 0;
}
示例#5
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *fp = NULL;
	
	if (argc < 2)
	{
		usage();
		exit(1);
	}

	parse_options(argc, argv); // opcoes

	if ((fp = fopen(argv[argc-1], "rb")) == NULL)
		EXIT_ERROR("file not found or unreadable");

	pe_init(&pe, fp); // inicializa o struct pe

	if (!is_pe(&pe))
		EXIT_ERROR("not a valid PE file");

	// dos header
	if (config.dos || config.all_headers || config.all)
	{
		IMAGE_DOS_HEADER dos;

		if (pe_get_dos(&pe, &dos))
			print_dos_header(&dos);
		else { EXIT_ERROR("unable to read DOS header"); }
	}

	// coff/file header
	if (config.coff || config.all_headers || config.all)
	{
		IMAGE_COFF_HEADER coff;

		if (pe_get_coff(&pe, &coff))
			print_coff_header(&coff);
		else { EXIT_ERROR("unable to read COFF file header"); }
	}

	// optional header
	if (config.opt || config.all_headers || config.all)
	{
		if (pe_get_optional(&pe))
			print_optional_header(&pe);
		else { EXIT_ERROR("unable to read Optional (Image) file header"); }
	}

	// directories
	if (config.dirs || config.all)
	{
		if (pe_get_directories(&pe))
			print_directories(&pe);
		else { EXIT_ERROR("unable to read the Directories entry from Optional header"); }
	}
	
	// imports
	if (config.imports || config.all)
	{
		if (pe_get_directories(&pe))
			print_imports(&pe);
		else { EXIT_ERROR("unable to read the Directories entry from Optional header"); }
	}	

	// exports
	if (config.exports || config.all)
	{
		if (pe_get_directories(&pe))
			print_exports(&pe);
		else
			{ EXIT_ERROR("unable to read directories from optional header"); }
	}

	// sections
	if (config.all_sections || config.all)
	{
		if (pe_get_sections(&pe))
			print_sections(&pe);
		else { EXIT_ERROR("unable to read sections"); }
	}

	// free
	pe_deinit(&pe);
	return 0;
}