Ejemplo n.º 1
0
//Adding the ProcessHeaps to the generic Memory Ranges
BOOL ProcInfo::addProcessHeapsAndCheckAddress(ADDRINT eip){
	BOOL isEipDiscoveredHere = FALSE;
	W::SIZE_T BytesToAllocate;
	W::PHANDLE aHeaps;
	//getting the number of ProcessHeaps
	W::DWORD NumberOfHeaps = W::GetProcessHeaps(0, NULL);
    if (NumberOfHeaps == 0) {
		MYERRORE("Error in retrieving number of Process Heaps");
		return isEipDiscoveredHere;
	}
	//Allocating space for the ProcessHeaps Addresses
	W::SIZETMult(NumberOfHeaps, sizeof(*aHeaps), &BytesToAllocate);
	aHeaps = (W::PHANDLE)W::HeapAlloc(W::GetProcessHeap(), 0, BytesToAllocate);
	 if ( aHeaps == NULL) {
		MYERRORE("HeapAlloc failed to allocate space");
		return isEipDiscoveredHere;
	} 

	W::GetProcessHeaps(NumberOfHeaps,aHeaps);
	//Adding the memory range containing the ProcessHeaps to the  genericMemoryRanges
	 for (int i = 0; i < NumberOfHeaps; ++i) {
		MemoryRange processHeap;
		if(getMemoryRange((ADDRINT) aHeaps[i],processHeap)){
			genericMemoryRanges.push_back(processHeap);
			if(eip >= processHeap.StartAddress && eip <= processHeap.EndAddress){
				isEipDiscoveredHere = TRUE;
			}
		}
    }
	return isEipDiscoveredHere;
}
void ScyllaWrapperInterface::addImportFunctionToDumpReport(string reconstructed_imports_file){
	string line;
	std::ifstream myfile(reconstructed_imports_file);
	vector<string> imports;
	vector<ReportObject *> imports_report;
	int imports_number=0;
	//parsing the file to extract modules and functions names and populate json objects
	while (getline(myfile, line)){
        try{
			
			imports = Helper::split(line,' ');  //the format of the file is "module_name function_name"
			ReportObject *current_import = new ReportImportedFunction(imports.at(0), imports.at(1));
			imports_number++;
			imports_report.push_back(current_import);

		}catch (const std::out_of_range& ){ //handle possible missing information inside the file
			MYERRORE("Problem adding function to the imported function report line: %s",line.c_str());
		}	
	}
	
	//Saving the information to the report
	try{
		ReportDump& report_dump = Report::getInstance()->getCurrentDump();
		report_dump.setImportedFunctions(imports_report);
		report_dump.setNumberOfImports(imports_number);
	}
	catch (const std::out_of_range& ){
		MYERRORE("Problem creating ReportImportedFunction report");
	}

}
Ejemplo n.º 3
0
UINT32 YaraHeuristic::run(vector<string> paths_to_analyse){
	
	vector<string> global_matched_rules;
	bool result = false;
	for(vector<string>::iterator dump_to_analyse = paths_to_analyse.begin(); dump_to_analyse != paths_to_analyse.end(); dump_to_analyse++){
		vector<string> cur_matched_rules = analyseYara(*dump_to_analyse);
		global_matched_rules.insert(global_matched_rules.end(),cur_matched_rules.begin(),cur_matched_rules.end());
	}
	
	if(!global_matched_rules.empty()){
		result = true;
	}

	//Saving the information to the report
	try{
		ReportDump& report_dump = Report::getInstance()->getCurrentDump();
		ReportObject* yara_heur = new ReportYaraRules(result, global_matched_rules);
		report_dump.addHeuristic(yara_heur);
	}
	catch (const std::out_of_range& ){
		MYERRORE("Problem creating ReportYaraRules report");
	}	

	
	return 0;
}
/**Lauch external tool ScyllaDumper to dump the process with PID pid 
 scylla: string containing the path to the scyllaDumper executable
 pid: pid of the process to dump (Current PID if you want to use the Pin Instrumented Binary)
 curEip: curre
**/
UINT32 ScyllaWrapperInterface::launchScyllaDumpAndFix(std::string scylla,int pid, int curEip,std::string outputFile){	

	MYINFO("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
	MYINFO("LAUNCHING SCYLLADUMP AS AN EXTERNAL PROCESS!!");
	MYINFO("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
	MYINFO("CURR EIP  %x",curEip);

	W::DWORD exitCode;
	//Creating the string containing the arguments to pass to the ScyllaTest.exe
	std::stringstream scyllaArgsStream;
	scyllaArgsStream << scylla << " ";
	scyllaArgsStream <<  pid << " ";
	scyllaArgsStream << std::hex  << curEip << " ";
	scyllaArgsStream << outputFile << " ";
	std::string scyllaArgs = scyllaArgsStream.str();	

	//sprintf(scyllaArgs,"%s %d %x %s",scylla,pid,curEip,outputFile); //argv[0] is the name of the program
	MYINFO("Scylla cmd %s %s",scylla.c_str(),scyllaArgs.c_str());

	//Running external Scyllatest.exe executable
	W::STARTUPINFO si ={0};
	W::PROCESS_INFORMATION pi ={0};

	si.cb=sizeof(si);

	if(!W::CreateProcess(scylla.c_str(),(char *)scyllaArgs.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)){
		MYERRORE("(INITFUNCTIONCALL)Can't launch Scylla");
		return -5;
	}
	W::GetExitCodeProcess(pi.hProcess, &exitCode);
	W::WaitForSingleObject(pi.hProcess,INFINITE);
	W::CloseHandle(pi.hProcess);
	W::CloseHandle(pi.hThread);
	
	if(!existFile(outputFile)){
		MYERRORE("Scylla Can't dump the process");
		return exitCode;
	}
	MYINFO("Scylla Finished");
	return exitCode;
}
/**Lauch external tool ScyllaDumper to dump the process with PID pid 
 scylla : string containing the path to the scyllaDumper executable
 pid : pid of the process to dump (Current PID if you want to use the Pin Instrumented Binary)
 curEip : current eip of the program
 outputFile : the name of the dump we want to create
 tmpDump : name of the temp file
 call_plugin_falg : specify if a plugin has to be called if the iat-fix fails
 plugin_full_path : full path to the dll containing the plugin
**/
UINT32 ScyllaWrapperInterface::launchScyllaDumpAndFix(int pid, int curEip, std::string outputFile, std::string tmpDump,  bool call_plugin_flag, std::string plugin_full_path, std::string reconstructed_imports_file){	
	std::string scylla = config->getScyllaDumperPath();
	W::DWORD exitCode;
	//Creating the string containing the arguments to pass to the ScyllaTest.exe
	std::stringstream scyllaArgsStream;
	scyllaArgsStream << scylla << " ";
	scyllaArgsStream <<  pid << " ";
	scyllaArgsStream << std::hex  << curEip << " ";
	scyllaArgsStream << outputFile << " ";
	scyllaArgsStream << tmpDump << " ";
	scyllaArgsStream << reconstructed_imports_file << " ";
	scyllaArgsStream << call_plugin_flag << " ";
	scyllaArgsStream << plugin_full_path << " ";
	std::string scyllaArgs = scyllaArgsStream.str();	
	MYINFO("Scylla cmd %s %s",scylla.c_str(),scyllaArgs.c_str());
	//Running external Scyllatest.exe executable
	W::STARTUPINFO si ={0};
	W::PROCESS_INFORMATION pi ={0};
	si.cb=sizeof(si);

	if(!W::CreateProcess(scylla.c_str(),(char *)scyllaArgs.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)){
		MYERRORE("(INITFUNCTIONCALL)Can't launch Scylla");
		return -5;
	}
	W::GetExitCodeProcess(pi.hProcess, &exitCode);
	W::WaitForSingleObject(pi.hProcess,INFINITE);
	W::CloseHandle(pi.hProcess);
	W::CloseHandle(pi.hThread);

	if(!Helper::existFile(outputFile)){
		MYERRORE("Scylla Can't dump the process");
		return exitCode;
	}
	if(Helper::existFile(reconstructed_imports_file)){//exist file containing imported functions
		addImportFunctionToDumpReport(reconstructed_imports_file);
	
	}
	MYINFO("Scylla Finished");
	return SCYLLA_SUCCESS_FIX;
}
Ejemplo n.º 6
0
/**
Fill the MemoryRange passed as parameter with the startAddress and EndAddress of the memory location in which the address is contained
ADDRINT address:  address of which we want to retrieve the memory region
MemoryRange& range: MemoryRange which will be filled 
return TRUE if the address belongs to a memory mapped area otherwise return FALSE
**/
BOOL ProcInfo::getMemoryRange(ADDRINT address, MemoryRange& range){		
	W::MEMORY_BASIC_INFORMATION mbi;
	int numBytes = W::VirtualQuery((W::LPCVOID)address, &mbi, sizeof(mbi));
	if(numBytes == 0){
		MYERRORE("VirtualQuery failed");
		return FALSE;
	}	
	int start =  (int)mbi.BaseAddress;
	int end = (int)mbi.BaseAddress+ mbi.RegionSize;
	//get the stack base address by searching the highest address in the allocated memory containing the stack Address
	if((mbi.State == MEM_COMMIT || mbi.Type == MEM_MAPPED || mbi.Type == MEM_IMAGE ||  mbi.Type == MEM_PRIVATE) &&
		start <=address && address <= end){
		range.StartAddress = start;
		range.EndAddress = end;
		return TRUE;
	}
	else{
		MYERRORE("Address %08x  not inside mapped memory from %08x -> %08x or Type/State not correct ",address,start,end);
		MYINFO("state %08x   %08x",mbi.State,mbi.Type);
		return  FALSE;
	}		
}
Ejemplo n.º 7
0
vector<string> YaraHeuristic::analyseYara(string dump_to_analyse){

	string yara_rules_path = Config::getInstance()->getYaraRulesPath();
	string yara_exe_path = Config::getInstance()->getYaraExePath();	
	string yara_res_file = Config::getInstance()->getYaraResultPath();
	
	string raw_output = "";
	vector<string> matched_rules;
	W::SECURITY_ATTRIBUTES sa; 
    // Set the bInheritHandle flag so pipe handles are inherited. 
    sa.nLength = sizeof(W::SECURITY_ATTRIBUTES); 
    sa.bInheritHandle = TRUE; 
    sa.lpSecurityDescriptor = NULL; 

    // Create a pipe for the child process's STDOUT. 
    if ( ! W::CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0) ) {
		MYERRORE("Error creating Pipe for Yara");
        return vector<string>(); 
    }
    // Ensure the read handle to the pipe for STDOUT is not inherited
    if ( ! W::SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) ){
		MYERRORE("Error creating Pipe for Yara");
        return vector<string>(); 
    }
	W::PROCESS_INFORMATION  piResults;
	if(launchYara(yara_exe_path,yara_rules_path, dump_to_analyse, yara_res_file,&piResults )){

		raw_output = ReadFromPipe(piResults);
		matched_rules = parseYaraOutput(raw_output);
		//MYINFO("Yara raw output result %s",raw_output.c_str());
	}
	else{
		MYERRORE("error launching Yara");
	}
	return matched_rules;

}
Ejemplo n.º 8
0
BOOL YaraHeuristic::launchYara(std::string yara_path, std::string yara_rules_path, std::string yara_input_path,std::string yara_output,W::PROCESS_INFORMATION * piResults){
	//string YaraLauncherBat = Config::getInstance()->getBasePath() + YARA_LAUNCHER;

	//Running external idaPython script
	W::STARTUPINFO si ={0};
	si.hStdOutput = g_hChildStd_OUT_Wr;
    si.dwFlags |= STARTF_USESTDHANDLES;
	W::PROCESS_INFORMATION pi ={0};

	si.cb=sizeof(si);
	

	//NB There can be problem if using spaces inside the path

	std::string yara_arguments =  yara_path  + " " +                        //path to yara executable
                             yara_rules_path + " " +     //path to yara rules
							 yara_input_path;       //path to yara input file




	// Create a file batch which run the IdaPython script and execute it
	/*FILE *YaraLauncherFile = fopen(YaraLauncherBat.c_str(),"w");
	fwrite(YaraLauncher.c_str(),strlen(YaraLauncher.c_str()),1,YaraLauncherFile);
	fclose(YaraLauncherFile);*/

	MYINFO("Launching  Yara executable %s command line %s ",yara_path.c_str(),yara_arguments.c_str());

	if(!W::CreateProcess(yara_path.c_str(),(char *)yara_arguments.c_str(),NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)){
		MYERRORE("Can't launch Yara Error %d",W::GetLastError());
		return false;
	}

	//Timeout 30 sec for the YARA processing
	W::WaitForSingleObject(pi.hProcess,30000);
	W::CloseHandle(pi.hProcess);
	W::CloseHandle(pi.hThread);
    W::CloseHandle(g_hChildStd_OUT_Wr);
	
	*piResults = pi;

	MYINFO("Yara Finished");
	return true;

}
/**
Dump on disk the memory range written on the remote process address space with  
return a string containing the path of the dumped memory
**/
string ProcessInjectionModule::DumpRemoteWriteInterval(WriteInterval* item,W::DWORD pid){
	//Dump remote process memory for each item inside the  currentWriteSet
	W::SIZE_T dwBytesRead = 0;
	UINT32 size =  item->getAddrEnd()-item->getAddrBegin();
	unsigned char * buffer = (unsigned char *)malloc(size);
	W::HANDLE process = W::OpenProcess(PROCESS_VM_READ,false,pid);
	if(W::ReadProcessMemory(process,(W::LPVOID)item->getAddrBegin(),buffer,  size,&dwBytesRead)){
		string path = config->getWorkingDir()+ "/" + std::to_string((long double)pid) + "_" + getNameFromPid(pid) + ".bin";
		Helper::writeBufferToFile(buffer,size,path);
		MYINFO("Dumped remote injected memory inside pid %d to %s",pid,path.c_str());
		return path;
	}
	else{
		MYERRORE("Error reading injected process %d  memory %s",pid,W::GetLastError());
		return "";
	}	

}
UINT32 InitFunctionCall::run(ADDRINT curEip,WriteInterval wi){

	string idap_res_file = Config::getInstance()->getCurrentDetectedListPath();
	string  dumpFile = Config::getInstance()->getCurrentDumpFilePath();

	if(!existFile(dumpFile)){
		MYERRORE("Dump file hasn't been created");
		return -1;
	}

	launchIdaScript(Config::IDA_PATH, Config::IDAP_BAD_IMPORTS_CHECKER, Config::BAD_IMPORTS_LIST, idap_res_file, dumpFile);

	//Read the result of IdaPython script
	FILE *fd = fopen(idap_res_file.c_str(),"r");
	UINT32 file_size = getFileSize(fd);
	char * init_func_detected = (char *)malloc(file_size);
	fread(init_func_detected,file_size,1,fd);
	fclose(fd);
	MYWARN("Found init functions %s\n",init_func_detected);

	return 0;
}
BOOL InitFunctionCall::launchIdaScript(string idaw,string idaPythonScript,string idaPythonInput,string idaPythonOutput,string dumpFile){
	string idaScriptLauncher = Config::getInstance()->getBasePath() + IDAPYTHON_LAUNCHER;

	//Running external idaPython script
	W::STARTUPINFO si ={0};
	W::PROCESS_INFORMATION pi ={0};

	si.cb=sizeof(si);
	// Create a file batch which run the IdaPython script and execute it

	//Creating the string used to launch the idaPython script
	std::stringstream idaScriptStream;
	idaScriptStream << idaw << " -A -S";
	idaScriptStream << "\"" << idaPythonScript << " " << idaPythonInput << " " << idaPythonOutput << "\" ";
	idaScriptStream << dumpFile << " ";
	string idaScript = idaScriptStream.str();	

	FILE *idaLauncherFile = fopen(idaScriptLauncher.c_str(),"w");
	fwrite(idaScript.c_str(),strlen(idaScript.c_str()),1,idaLauncherFile);
	fclose(idaLauncherFile);
	MYINFO("Launching the IdaPython Script %s Containing %s",idaLauncherFile,idaScript.c_str());
	
	
	if(!W::CreateProcess(idaScriptLauncher.c_str(),NULL,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)){
		MYERRORE("Can't launch idaPythonScript");
		return false;
	}

	W::WaitForSingleObject(pi.hProcess,INFINITE);
	W::CloseHandle(pi.hProcess);
	W::CloseHandle(pi.hThread);
	
	MYINFO("idaPythonScript Finished");
	return true;

}