コード例 #1
0
ファイル: Function.cpp プロジェクト: b2kguga/CodesAndNotes
int KFuncTable::InterceptWin32(void)
{
    int no = 0;

//	DebugBreak();

    for (int i=0; i<m_funcno; i++)
        if ( (m_func[i].f_kind==FUNC_WIN32API) & !m_func[i].f_hooked )
        // if there is an unhooked win32 function
		{
			int module = m_func[i].f_module;

			// if caller and callee are the same module, patch function target
			if ( strcmp(CallerName(module), CalleeName(module))==0 )
			{
				if ( directpatcher.Patch(ModHandle(module), GetFuncName(i), 
										 i, ProxyProlog,
										 (unsigned long *) &  m_func[i].f_oldaddress) )
					no ++;
			}
			else
			{
				const char *caller  = CallerName(module);
				const char *address = (const char *) ModHandle(module);

				// if caller module is loaded into current process, hack in it.
				if (address)
					no += InterceptWin32(caller, address);
			}
		}

    return no;
}
コード例 #2
0
ファイル: abstract_expression.cpp プロジェクト: foche/peloton
void AbstractExpression::DeduceExpressionName() {
  // If alias exists, it will be used in TrafficCop
  if (!alias.empty()) return;

  for (auto &child : children_) child->DeduceExpressionName();

  // Aggregate expression already has correct expr_name_
  if (ExpressionUtil::IsAggregateExpression(exp_type_)) return;

  auto op_str = ExpressionTypeToString(exp_type_, true);
  auto children_size = children_.size();
  if (exp_type_ == ExpressionType::FUNCTION) {
    auto expr = (FunctionExpression *)this;
    expr_name_ = expr->GetFuncName() + "(";
    for (size_t i = 0; i < children_size; i++) {
      if (i > 0) expr_name_.append(",");
      expr_name_.append(GetChild(i)->expr_name_);
    }
    expr_name_.append(")");
  } else {
    PL_ASSERT(children_size <= 2);
    if (children_size == 2) {
      expr_name_ = GetChild(0)->expr_name_ + " " + op_str + " " +
                   GetChild(1)->expr_name_;
    } else if (children_size == 1) {
      expr_name_ = op_str + " " + GetChild(0)->expr_name_;
    }
  }
}
コード例 #3
0
ファイル: Function.cpp プロジェクト: b2kguga/CodesAndNotes
FARPROC KFuncTable::GetProcAddr(int funcid)
{
    int mod = m_func[funcid].f_module;

    switch ( m_func[funcid].f_kind )
	{
		case FUNC_COMMETHOD:
		{
			const unsigned * pFunc = (const unsigned *) VTable(mod);
			assert(pFunc);

			return (FARPROC) pFunc[m_func[funcid].f_methodid];
		}
		break;

		case FUNC_WIN32API:
	    {
		    HINSTANCE hModule = ModHandle(m_func[funcid].f_module);
			assert(hModule);

			FARPROC fp = GetProcAddress(hModule, GetFuncName(funcid));

//			assert(fp);

			if ( fp==NULL )
			{
				char temp[128];

				wsprintf(temp, "Not found module %d at %x, func %s at %x",
					m_func[funcid].f_module, hModule, GetFuncName(funcid), fp);

				Send(M_TEXT, 0, 0, temp);
			}

			return fp;
		}

		case FUNC_SYSCALL:
			return m_func[funcid].f_oldaddress;

		default:
			assert(false);
    }

	return NULL;
}
コード例 #4
0
void CParmChCompareDlg::OnFunc() 
{
   UpdateData();
   m_Func = GetFuncName(m_FuncIdx);
   m_pRun->SetValues(this);
   SetCompStr();
   UpdateData(FALSE);
}
コード例 #5
0
void CParmChCompareDlg::InitFuncButtons() 
{
   m_FuncIdx = -1;
   for (int i=0; i<CRunChCompare::FUNC_NUM; i++) {
      CFunc func = GetFuncName(i);
      m_FuncButton[i].SetWindowText(func);
      if (m_Func == func) m_FuncIdx = i;
   }
   m_FuncButton[CRunChCompare::FUNC_COMP_CASE].EnableWindow(m_Func.SrcType() == pp16u);
}
コード例 #6
0
void ParseScript()
{
	char str[512];
	
	while(!feof(infile))
	{	
		memset(str,'\0',512);
		fgets(str,512,infile);
		
		switch(GetType(str))
		{
			case 1:
			{
				int opcode = GetID(str);
				
				if(opcode!=-1)
				{
					Push(&bytestack,opcode,1);
					PushArgs(&bytestack,str,opcode,4);
				}
			}
			break;
			
			case 2:
			{
				char *name = GetFuncName(str);
				int opcode = GetOpcode(name);
				
				Push(&bytestack,opcode,1);
				PushArgs(&bytestack,str,opcode,strlen(name));
				
				free(name);
			}
			break;
			
			case 3:
			{
				int id = GetID(str);
				
				if(id!=-1)
				{
					PushInt(&labelstack,bytestack.size,id);
					scrhead.labels.size++;
				}
				else
				{
					printf("Problem parsing label: %s",str);
					exit(1);
				}
			}
			break;
				
			case 4:
			{
				int id = GetID(str);
				
				if(id!=-1)
				{
					//Push(&markerstack,id,4);
					markerstack[id] = bytestack.size;
					scrhead.markers.size = 100;
				}
				else
				{
					printf("Problem parsing marker: %s",str);
					exit(1);
				}
			}
			break;
				
			case 5:
			{
				FILE *textfile = NULL;
				
				while(str[strlen(str)-1]=='\r' || str[strlen(str)-1]=='\n')
					str[strlen(str)-1] = '\0';
					
				textfile = fopen(str+9,"rb");
				
				if(!textfile)
				{
					printf("Could not open %s\n",str+9);
					exit(1);
				}
				
				ParseText(textfile);
				fclose(textfile);
			}
			break;
			
			case 6:
			{
				int t = 0;
				sscanf(str+1,"%x",&t);
				
				if(scrhead.unk12.size==0)
					unk12stack = (int*)calloc(1,sizeof(int));
				else
					unk12stack = (int*)realloc(unk12stack,(scrhead.unk12.size+1)*sizeof(int));
				
				unk12stack[scrhead.unk12.size++] = t;
			}
			break;
			
			case 7:
			{
				int t = 0;
				sscanf(str+1,"%x",&t);
				
				if(scrhead.unk13.size==0)
					unk13stack = (int*)calloc(1,sizeof(int));
				else
					unk13stack = (int*)realloc(unk13stack,(scrhead.unk13.size+1)*sizeof(int));
					
				unk13stack[scrhead.unk13.size++] = t;
			}
			break;
		
			default:
				break;
		}
	}
}
コード例 #7
0
//写文件
VOID WriteScriptFile()
{
	CHAR buf[256];
	tsnprintf(buf,256,__FILE__);
	CHAR* pStr = strrchr(buf,'\\');
	strcpy(pStr+1,"ScriptFuncForDesigner.h");
	FILE* fpScriptFile = fopen(buf,"w");

	CHAR** pScanFile = pLuaFnTblFile;
	while(*pScanFile)
	{
		CHAR buf[_MAX_PATH];
		tsnprintf(buf,256,__FILE__);
		CHAR* pStr = strrchr(buf,'\\');
		strcpy(pStr+1,*pScanFile);
		FILE* fp = fopen(buf,"r");

		if( fp != NULL  && fpScriptFile != NULL) 
		{
			//写文件头
			fprintf(fpScriptFile,"%s\t%s\n","脚本系统C导出函数文档",*pScanFile);

			CHAR line[_MAX_PATH * 4];
			
	
			CHAR *pStr1,*pStr2;//,*pStr3,*pStr4;
			INT linenum = 0;
			BOOL commentBegin = FALSE;
			BOOL beginNamaSpace = FALSE;
			BOOL bDelim = FALSE;
			while( fgets( line, sizeof( line), fp)) 
			{	
				if(strstr(line,"namespace"))
					beginNamaSpace = TRUE;
				if(!beginNamaSpace)
					continue;
		
				if(strstr(line,"endnamespace"))
					break;


				if(strstr(line,"/**"))
				{
					commentBegin = TRUE;
				}
				if(strstr(line,"*/"))
				{
					fprintf(fpScriptFile,"%s",line);
					commentBegin = FALSE;
				}
				if(commentBegin)
				{
					fprintf(fpScriptFile,"%s",line);
					continue;
				}

				if( (pStr1 = strstr(line,"INT")) && (pStr2 = strstr(line,"Lua_State")) && (pStr2 > pStr1))//简化 
				{
					Assert((pStr2 - pStr1) <= NAMELEN);
					
					const CHAR* temp = GetFuncName(pStr1,pStr2);
					
					for(int i=0;i<numReg;i++)
					{
						if(!strcmp(regInfo[i].funcname,temp))
						{
							for(int j=0;j<regInfo[i].regCount;j++)
								fprintf(fpScriptFile,"\t该函数注册为 %s\n",regInfo[i].regname[j]);
						}
					}
					
					//剔出Lua_State描述
					/*char* pDelim = strchr(line,',');
					if(pDelim){
						char szLine[_MAX_PATH];
						memset(szLine,0,_MAX_PATH);
						strncpy(szLine,line,pStr2-line);
						strcat(szLine,++pDelim);
						fprintf(fpScriptFile,"%s\n\n",szLine);
					}
					else{*/
						//fprintf(fpScriptFile,"%s\n\n",line);
					//}
					
						char* pDelim = strchr(line,'{');
						if(pDelim == NULL){
							bDelim = TRUE;
							//fprintf(fpScriptFile,"%s",line);
						}
						else{
							fprintf(fpScriptFile,"%s\n\n",line);
						}
					

				}

				if(strchr(line,'{') && bDelim == TRUE)
				{
					fprintf(fpScriptFile,"\n\n");
					bDelim = FALSE;
				}
				if(bDelim)
				{
					fprintf(fpScriptFile,"%s",line);
				}

			}
			fclose(fp);
			
		}

		pScanFile++;//读下一个文件
	}

	if(fpScriptFile)
	{
		//写文件尾
		fprintf(fpScriptFile,"文档生成日期:%d年%d月%d日%d时",g_pTimeManager->GetYear(),g_pTimeManager->GetMonth(),g_pTimeManager->GetDay(),g_pTimeManager->GetHour());
		fclose(fpScriptFile);
	}
}
コード例 #8
0
//读Lua函数表文件
VOID ReadLuaFnTblFiles()
{
	CHAR** pScanFile = pLuaFnTblFile;

	//扫描文件
	while(*pScanFile)
	{
		CHAR buf[256];
		tsnprintf(buf,256,__FILE__);
		CHAR* pStr = strrchr(buf,'\\');
		strcpy(pStr+1,*pScanFile);
		FILE* fp = fopen(buf,"r");

		if( fp != NULL) 
		{
			CHAR line[_MAX_PATH * 4];
			
	
			CHAR *pStr1,*pStr2,*pStr3,*pStr4;
			INT linenum = 0;
			BOOL commentBegin = FALSE;
			BOOL beginNamaSpace = FALSE;
			while( fgets( line, sizeof( line), fp)) 
			{	
				if(strstr(line,"namespace"))
					beginNamaSpace = TRUE;
				if(!beginNamaSpace)
					continue;
		
				if(strstr(line,"endnamespace"))
					break;

				//找到函数声明
				if( (pStr1 = strstr(line,"INT")) && (pStr2 = strstr(line,"Lua_State")) && (pStr2 > pStr1))//简化 
				{
					Assert((pStr2 - pStr1) <= NAMELEN);
					if((pStr2 - pStr1) <= NAMELEN)
					{
						const CHAR* temp = GetFuncName(pStr1,pStr2);
						Q_strncpyz(funcname[numFunc++],temp,NAMELEN);
					}
				}

				//找到已注册函数,没有考虑空格
				if((pStr1 = strstr(line,"FuncProto")))
				{
					pStr2 = strstr(line,")");
					pStr1 = pStr1 + strlen("FuncProto") + 1;

					pStr3 = strchr(line,'"');
					pStr4 = strchr(pStr3+1,'"');

					char szFuncName[NAMELEN];
					char szRegName[NAMELEN];

					Q_strncpyz(szFuncName,pStr1,pStr2 - pStr1 + 1);//加一
					Q_strncpyz(szRegName,pStr3 + 1,pStr4 - pStr3);

					BOOL toggle = FALSE; 
					INT i;
					for(i =0;i<numReg;i++)
					{
						if(!strcmp(regInfo[i].funcname,szFuncName))
						{
							toggle = TRUE;
							break;
						}
					}
				
					if(!toggle)
					{//第一次注册该函数
						Q_strncpyz(regInfo[numReg++].funcname,szFuncName,NAMELEN);
						Q_strncpyz(regInfo[numReg - 1].regname[regInfo[numReg -1].regCount++],szRegName,NAMELEN);						
					}
					else
					{
						Q_strncpyz(regInfo[i].regname[regInfo[i].regCount++],szRegName,NAMELEN);						
					}
				}
			}
			fclose(fp);

			
		}

		pScanFile++;//扫描下一个文件
	}
}
コード例 #9
0
ファイル: MIPSDis.cpp プロジェクト: Devil084/ppsspp
	{
		u32 off = disPC;
		int imm = (signed short)(op&0xFFFF)<<2;
		int rs = _RS;
		off += imm + 4;

		const char *name = MIPSGetName(op);
		sprintf(out, "%s\t%s, ->$%08x",name,RN(rs),off);
	}

	void Dis_Syscall(MIPSOpcode op, char *out)
	{
		u32 callno = (op>>6) & 0xFFFFF; //20 bits
		int funcnum = callno & 0xFFF;
		int modulenum = (callno & 0xFF000) >> 12;
		sprintf(out, "syscall\t	%s",/*PSPHLE::GetModuleName(modulenum),*/GetFuncName(modulenum, funcnum));
	}

	void Dis_ToHiloTransfer(MIPSOpcode op, char *out)
	{
		int rs = _RS;
		const char *name = MIPSGetName(op);
		sprintf(out, "%s\t%s",name,RN(rs));
	}
	void Dis_FromHiloTransfer(MIPSOpcode op, char *out)
	{
		int rd = _RD;
		const char *name = MIPSGetName(op);
		sprintf(out, "%s\t%s",name,RN(rd));
	}
コード例 #10
0
ファイル: sceKernelModule.cpp プロジェクト: iattilagy/ppsspp
Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *error_string)
{
	Module *module = new Module;
	kernelObjects.Create(module);
	memset(&module->nm, 0, sizeof(module->nm));

	u8 *newptr = 0;
	if (*(u32*)ptr == 0x4543537e) { // "~SCE"
		INFO_LOG(HLE, "~SCE module, skipping header");
		ptr += *(u32*)(ptr + 4);
	}

	if (*(u32*)ptr == 0x5053507e) { // "~PSP"
		// Decrypt module! YAY!
		INFO_LOG(HLE, "Decrypting ~PSP file");
		PSP_Header *head = (PSP_Header*)ptr;
		const u8 *in = ptr;
		u32 size = head->elf_size;
		if (head->psp_size > size)
		{
			size = head->psp_size;
		}
		newptr = new u8[head->elf_size + head->psp_size];
		ptr = newptr;
		int ret = pspDecryptPRX(in, (u8*)ptr, head->psp_size);
		if (ret == MISSING_KEY) {
			// This should happen for all "kernel" modules so disabling.
			// Reporting::ReportMessage("Missing PRX decryption key!");
			*error_string = "Missing key";
			delete [] newptr;
			module->isFake = true;
			strncpy(module->nm.name, head->modname, 28);
			module->nm.entry_addr = -1;
			module->nm.gp_value = -1;
			return module;
		}
		else if (ret <= 0)
		{
			ERROR_LOG(HLE, "Failed decrypting PRX! That's not normal! ret = %i\n", ret);
			Reporting::ReportMessage("Failed decrypting the PRX (ret = %i, size = %i, psp_size = %i)!", ret, head->elf_size, head->psp_size);
		}
	}

	if (*(u32*)ptr != 0x464c457f)
	{
		ERROR_LOG_REPORT(HLE, "Wrong magic number %08x", *(u32*)ptr);
		*error_string = "File corrupt";
		if (newptr) {
			delete [] newptr;
		}
		kernelObjects.Destroy<Module>(module->GetUID());
		return 0;
	}
	// Open ELF reader
	ElfReader reader((void*)ptr);

	if (!reader.LoadInto(loadAddress))
	{
		ERROR_LOG(HLE, "LoadInto failed");
		if (newptr)
		{
			delete [] newptr;
		}
		kernelObjects.Destroy<Module>(module->GetUID());
		return 0;
	}
	module->memoryBlockAddr = reader.GetVaddr();

	struct libent
	{
		u32 exportName; //default 0
		u16 bcdVersion;
		u16 moduleAttributes;
		u8 exportEntrySize;
		u8 numVariables;
		u16 numFunctions;
		u32 __entrytableAddr;
	};

	struct PspModuleInfo
	{
		// 0, 0, 1, 1 ?
		u16 moduleAttrs; //0x0000 User Mode, 0x1000 Kernel Mode
		u16 moduleVersion;
		// 28 bytes of module name, packed with 0's.
		char name[28];
		u32 gp;					 // ptr to MIPS GOT data	(global offset table)
		u32 libent;			 // ptr to .lib.ent section 
		u32 libentend;		// ptr to end of .lib.ent section 
		u32 libstub;			// ptr to .lib.stub section 
		u32 libstubend;	 // ptr to end of .lib.stub section 
	};

	SectionID sceModuleInfoSection = reader.GetSectionByName(".rodata.sceModuleInfo");
	PspModuleInfo *modinfo;
	if (sceModuleInfoSection != -1)
		modinfo = (PspModuleInfo *)Memory::GetPointer(reader.GetSectionAddr(sceModuleInfoSection));
	else
		modinfo = (PspModuleInfo *)Memory::GetPointer(reader.GetSegmentVaddr(0) + (reader.GetSegmentPaddr(0) & 0x7FFFFFFF) - reader.GetSegmentOffset(0));

	module->nm.gp_value = modinfo->gp;
	strncpy(module->nm.name, modinfo->name, 28);

	// Check for module blacklist - we don't allow games to load these modules from disc
	// as we have HLE implementations and the originals won't run in the emu because they
	// directly access hardware or for other reasons.
	for (u32 i = 0; i < ARRAY_SIZE(blacklistedModules); i++) {
		if (strcmp(modinfo->name, blacklistedModules[i]) == 0) {
			*error_string = "Blacklisted";
			if (newptr)
			{
				delete [] newptr;
			}
			module->isFake = true;
			module->nm.entry_addr = -1;
			return module;
		}
	}

	bool hasSymbols = false;
	bool dontadd = false;

	SectionID textSection = reader.GetSectionByName(".text");

	if (textSection != -1)
	{
		u32 textStart = reader.GetSectionAddr(textSection);
		u32 textSize = reader.GetSectionSize(textSection);

		if (!host->AttemptLoadSymbolMap())
		{
			hasSymbols = reader.LoadSymbols();
			if (!hasSymbols)
			{
				symbolMap.ResetSymbolMap();
				MIPSAnalyst::ScanForFunctions(textStart, textStart+textSize);
			}
		}
		else
		{
			dontadd = true;
		}
	}
	else if (host->AttemptLoadSymbolMap())
	{
		dontadd = true;
	}

	INFO_LOG(LOADER,"Module %s: %08x %08x %08x", modinfo->name, modinfo->gp, modinfo->libent,modinfo->libstub);

	struct PspLibStubEntry
	{
		u32 name;
		u16 version;
		u16 flags;
		u16 size;
		u16 numFuncs;
		// each symbol has an associated nid; nidData is a pointer
		// (in .rodata.sceNid section) to an array of longs, one
		// for each function, which identifies the function whose
		// address is to be inserted.
		//
		// The hash is the first 4 bytes of a SHA-1 hash of the function
		// name.	(Represented as a little-endian long, so the order
		// of the bytes is reversed.)
		u32 nidData;
		// the address of the function stubs where the function address jumps
		// should be filled in
		u32 firstSymAddr;
	};

	int numModules = (modinfo->libstubend - modinfo->libstub)/sizeof(PspLibStubEntry);

	DEBUG_LOG(LOADER,"Num Modules: %i",numModules);
	DEBUG_LOG(LOADER,"===================================================");

	PspLibStubEntry *entry = (PspLibStubEntry *)Memory::GetPointer(modinfo->libstub);

	int numSyms=0;
	for (int m = 0; m < numModules; m++) {
		const char *modulename;
		if (Memory::IsValidAddress(entry[m].name))
			modulename = (const char*)Memory::GetPointer(entry[m].name);
		else
			modulename = "(invalidname)";

		if (!Memory::IsValidAddress(entry[m].nidData)) {
			ERROR_LOG(LOADER, "Crazy niddata address %08x, skipping entire module", entry[m].nidData);
			continue;
		}
		u32 *nidDataPtr = (u32*)Memory::GetPointer(entry[m].nidData);
		// u32 *stubs = (u32*)Memory::GetPointer(entry[m].firstSymAddr);

		DEBUG_LOG(LOADER,"Importing Module %s, stubs at %08x",modulename,entry[m].firstSymAddr);

		for (int i=0; i<entry[m].numFuncs; i++)
		{
			u32 addrToWriteSyscall = entry[m].firstSymAddr+i*8;
			DEBUG_LOG(LOADER,"%s : %08x",GetFuncName(modulename, nidDataPtr[i]), addrToWriteSyscall);
			//write a syscall here
			if (Memory::IsValidAddress(addrToWriteSyscall))
				WriteSyscall(modulename, nidDataPtr[i], addrToWriteSyscall);
			if (!dontadd)
			{
				char temp[256];
				sprintf(temp,"zz_%s", GetFuncName(modulename, nidDataPtr[i]));
				symbolMap.AddSymbol(temp, addrToWriteSyscall, 8, ST_FUNCTION);
			}
			numSyms++;
		}
		DEBUG_LOG(LOADER,"-------------------------------------------------------------");
	}

	// Look at the exports, too.

	struct PspLibEntEntry
	{
		u32 name; /* ent's name (module name) address */
		u16 version;
		u16 flags;
		u8 size;
		u8 vcount;
		u16 fcount;
		u32 resident;
	};

	int numEnts = (modinfo->libentend - modinfo->libent)/sizeof(PspLibEntEntry);
	PspLibEntEntry *ent = (PspLibEntEntry *)Memory::GetPointer(modinfo->libent);
	for (int m=0; m<numEnts; m++)
	{
		const char *name;
		if (ent->size == 0)
			continue;

		if (ent->name == 0) {
			// ?
			name = module->nm.name;
		}
		else if (Memory::IsValidAddress(ent->name)) {
			name = (const char*)Memory::GetPointer(ent->name);
		}
		else {
			name = "invalid?";  // God Eater Burst
		}

		INFO_LOG(HLE,"Exporting ent %d named %s, %d funcs, %d vars, resident %08x", m, name, ent->fcount, ent->vcount, ent->resident);
		
		// Seen 0x00060005 in God Eater Burst
		if (Memory::IsValidAddress(ent->resident)) 
		{
			u32 *residentPtr = (u32*)Memory::GetPointer(ent->resident);

			for (u32 j = 0; j < ent->fcount; j++)
			{
				u32 nid = residentPtr[j];
				u32 exportAddr = residentPtr[ent->fcount + ent->vcount + j];

				switch (nid)
				{
				case NID_MODULE_START:
					module->nm.module_start_func = exportAddr;
					break;
				case NID_MODULE_STOP:
					module->nm.module_stop_func = exportAddr;
					break;
				case NID_MODULE_REBOOT_BEFORE:
					module->nm.module_reboot_before_func = exportAddr;
					break;
				case NID_MODULE_REBOOT_PHASE:
					module->nm.module_reboot_phase_func = exportAddr;
					break;
				case NID_MODULE_BOOTSTART:
					module->nm.module_bootstart_func = exportAddr;
					break;
				default:
					ResolveSyscall(name, nid, exportAddr);
				}
			}

			for (u32 j = 0; j < ent->vcount; j++)
			{
				u32 nid = residentPtr[ent->fcount + j];
				u32 exportAddr = residentPtr[ent->fcount + ent->vcount + ent->fcount + j];

				switch (nid)
				{
				case NID_MODULE_INFO:
					break;
				case NID_MODULE_START_THREAD_PARAMETER:
					if (Memory::Read_U32(exportAddr) != 3)
						WARN_LOG_REPORT(LOADER, "Strange value at module_start_thread_parameter export: %08x", Memory::Read_U32(exportAddr));
					module->nm.module_start_thread_priority = Memory::Read_U32(exportAddr + 4);
					module->nm.module_start_thread_stacksize = Memory::Read_U32(exportAddr + 8);
					module->nm.module_start_thread_attr = Memory::Read_U32(exportAddr + 12);
					break;
				case NID_MODULE_STOP_THREAD_PARAMETER:
					if (Memory::Read_U32(exportAddr) != 3)
						WARN_LOG_REPORT(LOADER, "Strange value at module_stop_thread_parameter export: %08x", Memory::Read_U32(exportAddr));
					module->nm.module_stop_thread_priority = Memory::Read_U32(exportAddr + 4);
					module->nm.module_stop_thread_stacksize = Memory::Read_U32(exportAddr + 8);
					module->nm.module_stop_thread_attr = Memory::Read_U32(exportAddr + 12);
					break;
				case NID_MODULE_REBOOT_BEFORE_THREAD_PARAMETER:
					if (Memory::Read_U32(exportAddr) != 3)
						WARN_LOG_REPORT(LOADER, "Strange value at module_reboot_before_thread_parameter export: %08x", Memory::Read_U32(exportAddr));
					module->nm.module_reboot_before_thread_priority = Memory::Read_U32(exportAddr + 4);
					module->nm.module_reboot_before_thread_stacksize = Memory::Read_U32(exportAddr + 8);
					module->nm.module_reboot_before_thread_attr = Memory::Read_U32(exportAddr + 12);
					break;
				case NID_MODULE_SDK_VERSION:
					DEBUG_LOG(LOADER, "Module SDK: %08x", Memory::Read_U32(exportAddr));
					break;
				default:
					DEBUG_LOG(LOADER, "Unexpected variable with nid: %08x", nid);
					break;
				}
			}
		}

		if (ent->size > 4)
		{
			ent = (PspLibEntEntry*)((u8*)ent + ent->size * 4);
		}
		else
		{
			ent++;
		}
	}

	module->nm.entry_addr = reader.GetEntryPoint();
	
	// use module_start_func instead of entry_addr if entry_addr is 0
	if (module->nm.entry_addr == 0)
		module->nm.entry_addr = module->nm.module_start_func;

	if (newptr)
	{
		delete [] newptr;
	}
	return module;
}
コード例 #11
0
ファイル: sceKernelModule.cpp プロジェクト: Ryalian/ppsspp
Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *error_string)
{
	Module *module = new Module;
	kernelObjects.Create(module);

	u8 *newptr = 0;

	if (*(u32*)ptr == 0x5053507e) { // "~PSP"
		// Decrypt module! YAY!
		INFO_LOG(HLE, "Decrypting ~PSP file");
		PSP_Header *head = (PSP_Header*)ptr;
		const u8 *in = ptr;
		u32 size = head->elf_size;
		if (head->psp_size > size)
		{
			size = head->psp_size;
		}
		newptr = new u8[head->elf_size + head->psp_size];
		ptr = newptr;
		pspDecryptPRX(in, (u8*)ptr, head->psp_size);
	}

	if (*(u32*)ptr == 0x4543537e) { // "~SCE"
		ERROR_LOG(HLE, "Wrong magic number %08x (~SCE, kernel module?)",*(u32*)ptr);
		*error_string = "Kernel module?";
		if (newptr)
		{
			delete [] newptr;
		}
		kernelObjects.Destroy<Module>(module->GetUID());
		return 0;
	}
	
	if (*(u32*)ptr != 0x464c457f)
	{
		ERROR_LOG(HLE, "Wrong magic number %08x",*(u32*)ptr);
		*error_string = "File corrupt";
		if (newptr)
		{
			delete [] newptr;
		}
		kernelObjects.Destroy<Module>(module->GetUID());
		return 0;
	}
	// Open ELF reader
	ElfReader reader((void*)ptr);

	if (!reader.LoadInto(loadAddress))
	{
		ERROR_LOG(HLE, "LoadInto failed");
		if (newptr)
		{
			delete [] newptr;
		}
		kernelObjects.Destroy<Module>(module->GetUID());
		return 0;
	}

	struct libent
	{
		u32 exportName; //default 0
		u16 bcdVersion;
		u16 moduleAttributes;
		u8 exportEntrySize;
		u8 numVariables;
		u16 numFunctions;
		u32 __entrytableAddr;
	};

	struct PspModuleInfo
	{
		// 0, 0, 1, 1 ?
		u16 moduleAttrs; //0x0000 User Mode, 0x1000 Kernel Mode
		u16 moduleVersion;
		// 28 bytes of module name, packed with 0's.
		char name[28];
		u32 gp;					 // ptr to MIPS GOT data	(global offset table)
		u32 libent;			 // ptr to .lib.ent section 
		u32 libentend;		// ptr to end of .lib.ent section 
		u32 libstub;			// ptr to .lib.stub section 
		u32 libstubend;	 // ptr to end of .lib.stub section 
	};

	SectionID sceModuleInfoSection = reader.GetSectionByName(".rodata.sceModuleInfo");
	PspModuleInfo *modinfo;
	if (sceModuleInfoSection != -1)
		modinfo = (PspModuleInfo *)Memory::GetPointer(reader.GetSectionAddr(sceModuleInfoSection));
	else
		modinfo = (PspModuleInfo *)Memory::GetPointer(reader.GetVaddr() + (reader.GetSegmentPaddr(0) & 0x7FFFFFFF) - reader.GetSegmentOffset(0));

	// Check for module blacklist - we don't allow games to load these modules from disc
	// as we have HLE implementations and the originals won't run in the emu because they
	// directly access hardware or for other reasons.
	for (u32 i = 0; i < ARRAY_SIZE(blacklistedModules); i++) {
		if (strcmp(modinfo->name, blacklistedModules[i]) == 0) {
			*error_string = "Blacklisted";
			if (newptr)
			{
				delete [] newptr;
			}
			kernelObjects.Destroy<Module>(module->GetUID());
			return 0;
		}
	}

	bool hasSymbols = false;
	bool dontadd = false;

	SectionID textSection = reader.GetSectionByName(".text");

	if (textSection != -1)
	{
		u32 textStart = reader.GetSectionAddr(textSection);
		u32 textSize = reader.GetSectionSize(textSection);

		if (!host->AttemptLoadSymbolMap())
		{
			hasSymbols = reader.LoadSymbols();
			if (!hasSymbols)
			{
				symbolMap.ResetSymbolMap();
				MIPSAnalyst::ScanForFunctions(textStart, textStart+textSize);
			}
		}
		else
		{
			dontadd = true;
		}
	}

	module->gp_value = modinfo->gp;
	strncpy(module->name, modinfo->name, 28);

	INFO_LOG(LOADER,"Module %s: %08x %08x %08x", modinfo->name, modinfo->gp, modinfo->libent,modinfo->libstub);

	struct PspLibStubEntry
	{
		u32 name;
		u16 version;
		u16 flags;
		u16 size;
		u16 numFuncs;
		// each symbol has an associated nid; nidData is a pointer
		// (in .rodata.sceNid section) to an array of longs, one
		// for each function, which identifies the function whose
		// address is to be inserted.
		//
		// The hash is the first 4 bytes of a SHA-1 hash of the function
		// name.	(Represented as a little-endian long, so the order
		// of the bytes is reversed.)
		u32 nidData;
		// the address of the function stubs where the function address jumps
		// should be filled in
		u32 firstSymAddr;
	};

	int numModules = (modinfo->libstubend - modinfo->libstub)/sizeof(PspLibStubEntry);

	DEBUG_LOG(LOADER,"Num Modules: %i",numModules);
	DEBUG_LOG(LOADER,"===================================================");

	PspLibStubEntry *entry = (PspLibStubEntry *)Memory::GetPointer(modinfo->libstub);

	int numSyms=0;
	for (int m = 0; m < numModules; m++)
	{
		const char *modulename = (const char*)Memory::GetPointer(entry[m].name);
		u32 *nidDataPtr = (u32*)Memory::GetPointer(entry[m].nidData);
		// u32 *stubs = (u32*)Memory::GetPointer(entry[m].firstSymAddr);

		DEBUG_LOG(LOADER,"Importing Module %s, stubs at %08x",modulename,entry[m].firstSymAddr);

		for (int i=0; i<entry[m].numFuncs; i++)
		{
			u32 addrToWriteSyscall = entry[m].firstSymAddr+i*8;
			DEBUG_LOG(LOADER,"%s : %08x",GetFuncName(modulename, nidDataPtr[i]), addrToWriteSyscall);
			//write a syscall here
			WriteSyscall(modulename, nidDataPtr[i], addrToWriteSyscall);
			if (!dontadd)
			{
				char temp[256];
				sprintf(temp,"zz_%s", GetFuncName(modulename, nidDataPtr[i]));
				symbolMap.AddSymbol(temp, addrToWriteSyscall, 8, ST_FUNCTION);
			}
			numSyms++;
		}
		DEBUG_LOG(LOADER,"-------------------------------------------------------------");
	}

	// Look at the exports, too.

	struct PspLibEntEntry
	{
		u32 name; /* ent's name (module name) address */
		u16 version;
		u16 flags;
		u8 size;
		u8 vcount;
		u16 fcount;
		u32 resident;
	};

	int numEnts = (modinfo->libentend - modinfo->libent)/sizeof(PspLibEntEntry);
	PspLibEntEntry *ent = (PspLibEntEntry *)Memory::GetPointer(modinfo->libent);
	for (int m=0; m<numEnts; m++)
	{
		const char *name;
		if (ent->size == 0)
		{
			continue;
		}

		if (ent->name == 0)
		{
			// ?
			name = module->name;
		}
		else
		{
			name = (const char*)Memory::GetPointer(ent->name);
		}

		INFO_LOG(HLE,"Exporting ent %d named %s, %d funcs, %d vars, resident %08x", m, name, ent->fcount, ent->vcount, ent->resident);
		
		u32 *residentPtr = (u32*)Memory::GetPointer(ent->resident);

		for (u32 j = 0; j < ent->fcount; j++)
		{
			u32 nid = residentPtr[j];
			u32 exportAddr = residentPtr[ent->fcount + ent->vcount + j];
			ResolveSyscall(name, nid, exportAddr);
		}
		if (ent->size > 4)
		{
			ent = (PspLibEntEntry*)((u8*)ent + ent->size * 4);
		}
		else
		{
			ent++;
		}
	}

	module->entry_addr = reader.GetEntryPoint();

	if (newptr)
	{
		delete [] newptr;
	}
	return module;
}