Ejemplo n.º 1
0
static void print_exports(PE_FILE *pe)
{
	QWORD va;
	IMAGE_EXPORT_DIRECTORY exp;
	DWORD rva, aux, faddr = 0;

	va = pe->directories_ptr[IMAGE_DIRECTORY_ENTRY_EXPORT] ? 
	pe->directories_ptr[IMAGE_DIRECTORY_ENTRY_EXPORT]->VirtualAddress : 0;

	if (!va)
	{
		fprintf(stderr, "export directory not found\n");
		return;
	}

	if (fseek(pe->handle, rva2ofs(pe, va), SEEK_SET))
		EXIT_ERROR("unable to seek until export directory");

	if (!fread(&exp, sizeof(exp), 1, pe->handle))
		EXIT_ERROR("unable to read export directory");

	if (fseek(pe->handle, rva2ofs(pe, exp.AddressOfNames), SEEK_SET))
		EXIT_ERROR("unable to seek");

	if (!fread(&rva, sizeof(rva), 1, pe->handle))
		EXIT_ERROR("unable to read");

	if (fseek(pe->handle, rva2ofs(pe, rva), SEEK_SET))
		EXIT_ERROR("unable to seek");

	output("Exported functions", NULL);
	for (unsigned i=0; i<exp.NumberOfNames; i++)
	{
		char c=1, addr[30], fun[300];

		aux = ftell(pe->handle);
		fseek(pe->handle, exp.AddressOfFunctions + sizeof(DWORD) * i, SEEK_SET);
		fread(&faddr, sizeof(faddr), 1, pe->handle);
		fseek(pe->handle, aux, SEEK_SET);
		memset(&fun, 0, sizeof(fun));
		memset(&addr, 0, sizeof(addr));
		snprintf(addr, 30, "%#x", faddr);

		for (unsigned j=0; c; j++)
		{
			fread(&c, sizeof(c), 1, pe->handle);
			fun[j] = c;
		}
		output(addr, fun);
	}
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *fp = NULL;
	unsigned long rva = 0;

	parse_options(argc, argv); // opcoes

	if (argc != 3)
	{
		usage();
		exit(1);
	}

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

	rva = (unsigned long) strtol(argv[1], NULL, 0);

	if (!rva)
		EXIT_ERROR("invalid RVA");


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

	if (!ispe(&pe))
		EXIT_ERROR("not a valid PE file");
		
	printf("%#"PRIx64"\n", rva2ofs(&pe, rva));
	// libera a memoria
	pe_deinit(&pe);
	
	return 1;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *dbfile = NULL, *fp = NULL;
	QWORD ep_offset, pesize;
	char value[MAX_MSG];
	unsigned char *pe_data;

	if (argc < 2)
	{
		usage();
		exit(1);
	}

	memset(&config, 0, sizeof(config));
	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 (!ispe(&pe))
		EXIT_ERROR("invalid PE file");

	if (!pe_get_optional(&pe))
		EXIT_ERROR("unable to read optional header");

   if (!(ep_offset = rva2ofs(&pe, pe.entrypoint)))
		EXIT_ERROR("unable to get entrypoint offset");
	
	pesize = pe_get_size(&pe);
	pe_data = (unsigned char *) xmalloc(pesize);
	
	//if (fseek(pe.handle, ep, SEEK_SET))
		//EXIT_ERROR("unable to seek to entrypoint offset");
	
	if (!fread(pe_data, pesize, 1, pe.handle))
		EXIT_ERROR("unable to read entrypoint data");
	
	if (!loaddb(&dbfile))
		fprintf(stderr, "warning: without valid database file, %s will search in generic mode only\n", PROGRAM);
	
	// packer by signature
	if (compare_signature(pe_data, ep_offset, dbfile, value));
	// generic detection
	else if (generic_packer(&pe, ep_offset))
		snprintf(value, MAX_MSG, "generic");
	else
		snprintf(value, MAX_MSG, "no packer found");
	
	free(pe_data);
	output("packer", value);

	if (dbfile)
		fclose(dbfile);
	pe_deinit(&pe);
	
	return 0;
}
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *fp = NULL;
	DWORD ep, stub_offset;
	int callbacks;
	double entropy;
//	unsigned int num_sections;

	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");

	// File entropy
	entropy = calculate_entropy_file(&pe);

	if(entropy < 7.0)
		snprintf(value, MAX_MSG, "normal (%f)", entropy);
	else
		snprintf(value, MAX_MSG, "packed (%f)", entropy);
	output("file entropy", value);
        memset(&value, 0, sizeof(value));

	if (!pe_get_optional(&pe))
		return 1;

  	ep = (pe.optional_ptr->_32 ? pe.optional_ptr->_32->AddressOfEntryPoint :
	(pe.optional_ptr->_64 ? pe.optional_ptr->_64->AddressOfEntryPoint : 0));

	// fake ep
	if (ep == 0)
		snprintf(value, MAX_MSG, "null");
	else if (pe_check_fake_entrypoint(&pe, &ep))
		if (config.verbose)
			snprintf(value, MAX_MSG, "fake - va: %#x - raw: %#"PRIx64, ep, rva2ofs(&pe, ep));
		else
			snprintf(value, MAX_MSG, "fake");
	else
		if (config.verbose)
			snprintf(value, MAX_MSG, "normal - va: %#x - raw: %#"PRIx64, ep, rva2ofs(&pe, ep));
		else
			snprintf(value, MAX_MSG, "normal");

	output("entrypoint", value);

	// dos stub
	memset(&value, 0, sizeof(value));
	if (!normal_dos_stub(&pe, &stub_offset))
	{
		if (config.verbose)
			snprintf(value, MAX_MSG, "suspicious - raw: %#x", stub_offset);
		else
			snprintf(value, MAX_MSG, "suspicious");
	}
	else
		snprintf(value, MAX_MSG, "normal");

	output("DOS stub", value);

	// tls callbacks
	callbacks = pe_get_tls_callbacks(&pe);

	if (callbacks == 0)
		snprintf(value, MAX_MSG, "not found");
	else if (callbacks == -1)
		snprintf(value, MAX_MSG, "found - no functions");
	else if (callbacks >0)
		snprintf(value, MAX_MSG, "found - %d function(s)", callbacks);

	output("TLS directory", value);
	memset(&value, 0, sizeof(value));

	// section analysis
	print_strange_sections(&pe);

	// no imagebase
	if (!normal_imagebase(&pe))
	{
		if (config.verbose)
			snprintf(value, MAX_MSG, "suspicious - %#"PRIx64, pe.imagebase);
		else
			snprintf(value, MAX_MSG, "suspicious");
	}
	else
	{
		if (config.verbose)
			snprintf(value, MAX_MSG, "normal - %#"PRIx64, pe.imagebase);
		else
			snprintf(value, MAX_MSG, "normal");
	}
	output("imagebase", value);

	// invalid timestamp
	IMAGE_COFF_HEADER coff;

	if (!pe_get_coff(&pe, &coff))
		EXIT_ERROR("unable to read coff header");

	print_timestamp(&coff.TimeDateStamp);

	pe_deinit(&pe);

	return 0;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
static void print_imports(PE_FILE *pe)
{
	QWORD va; // store temporary addresses
	long aux;
	IMAGE_IMPORT_DESCRIPTOR id;
	char c = 0;
	char dllname[MAX_DLL_NAME];
	unsigned int i;

	va = pe->directories_ptr[IMAGE_DIRECTORY_ENTRY_IMPORT] ? 
	pe->directories_ptr[IMAGE_DIRECTORY_ENTRY_IMPORT]->VirtualAddress : 0;

	if (!va)
		EXIT_ERROR("import directory not found");

	if (fseek(pe->handle, rva2ofs(pe, va), SEEK_SET))
		EXIT_ERROR("error seeking file");
	
	memset(&id, 0, sizeof(id));
	memset(&dllname, 0, sizeof(dllname));

	output("Imported functions", NULL);
	while (1)
	{
		if (!fread(&id, sizeof(id), 1, pe->handle))
			return;

		if (!id.u1.OriginalFirstThunk)
			break;

		aux = ftell(pe->handle);
		va = rva2ofs(pe, id.Name);
		
		if (!va)
			return;

		// shortcut to read DLL name
		if (fseek(pe->handle, va, SEEK_SET))
			return;

		// print dll name
		for (i=0; i < MAX_DLL_NAME; i++)
		{
			fread(&c, sizeof(c), 1, pe->handle);
			
			if (!c)
				break;
			
			dllname[i] = c;
		}
		
		output(dllname, NULL);
		memset(&dllname, 0, sizeof(dllname));
		
		if (fseek(pe->handle, aux, SEEK_SET)) // restore file pointer
			return;

		// search for dll imported functions
		va = rva2ofs(pe, id.u1.OriginalFirstThunk);

		if (!va)
			return;

		print_imported_functions(pe, va);
	}
}
Ejemplo n.º 7
0
static void print_imported_functions(PE_FILE *pe, long offset)
{
	QWORD fptr = 0; // pointer to functions
	long aux2, aux = ftell(pe->handle);
	WORD hint = 0; // function number
	char c;
	char fname[MAX_FUNCTION_NAME];
	char hintstr[16];
	unsigned int i;
	
	if (fseek(pe->handle, offset, SEEK_SET))
		return;

	memset(&fname, 0, sizeof(fname));
	memset(&hintstr, 0, sizeof(hintstr));
	
	while (1)
	{
		if (!fread(&fptr, (pe->architecture == PE64) ? sizeof(QWORD) : sizeof(DWORD), 1, pe->handle))
			return;
		
		if (!fptr)
			break;

		// function without name (test msb)
		if (fptr & ((pe->architecture == PE64) ? IMAGE_ORDINAL_FLAG64 : IMAGE_ORDINAL_FLAG32))
			snprintf(hintstr, 15, "%"PRIu64, fptr & 0x0fffffff);
		else
		{
			// save file pointer in functions array
			aux2 = ftell(pe->handle);
		
			if (fseek(pe->handle, rva2ofs(pe, fptr), SEEK_SET))
				return;

			// follow function pointer
			if (!fread(&hint, sizeof(hint), 1, pe->handle))
				return;
		
			for (i=0; i<MAX_FUNCTION_NAME; i++)
			{
				if (!fread(&c, sizeof(c), 1, pe->handle))
					return;
			
				if (!isprint((int)c)) // 0 and non-printable
					break;
			
				fname[i] = c;
			}
			snprintf(hintstr, 15, "%d", hint);
		
			// restore file pointer to functions array
			if (fseek(pe->handle, aux2, SEEK_SET))
				return;
		}

		// print things
		output(hintstr, fname);
		memset(&fname, 0, sizeof(fname));
		memset(&hintstr, 0, sizeof(hintstr));
	}
		
	fseek(pe->handle, aux, SEEK_SET);
}