mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-11-30 18:10:29 +00:00
277 lines
6.0 KiB
ObjectPascal
277 lines
6.0 KiB
ObjectPascal
{$mode objfpc}{$H+}
|
|
|
|
Uses
|
|
classes,
|
|
Sysutils,
|
|
sha1,
|
|
gmap;
|
|
|
|
type
|
|
TQWORDCompare=class
|
|
class function c(var a,b:QWORD):boolean; static;
|
|
end;
|
|
TMapSym=specialize TMap<QWORD,RawByteString,TQWORDCompare>;
|
|
|
|
class function TQWORDCompare.c(var a,b:QWORD):boolean;
|
|
begin
|
|
Result:=a<b;
|
|
end;
|
|
|
|
function ps4_nid_hash(name:PChar):QWORD;
|
|
const
|
|
salt:array[0..15] of Byte=($51,$8D,$64,$A6,$35,$DE,$D8,$C1,$E6,$B0,$39,$B1,$C3,$E5,$52,$30);
|
|
var
|
|
Context:TSHA1Context;
|
|
Digest:TSHA1Digest;
|
|
begin
|
|
SHA1Init(Context);
|
|
SHA1Update(Context,name^,StrLen(name));
|
|
SHA1Update(Context,salt,Length(salt));
|
|
SHA1Final(Context,Digest);
|
|
Result:=PQWORD(@Digest)^;
|
|
end;
|
|
|
|
function DecodeValue64(strEnc:PAnsiChar;len:SizeUint;var nVal:QWORD):Boolean;
|
|
const
|
|
nEncLenMax=11;
|
|
var
|
|
i,nIndex:Integer;
|
|
begin
|
|
Result:=False;
|
|
nVal:=0;
|
|
if (len>nEncLenMax) or (len=0) then Exit;
|
|
For i:=0 to len-1 do
|
|
begin
|
|
case strEnc[i] of
|
|
'A'..'Z':nIndex:=Byte(strEnc[i])-Byte('A')+0;
|
|
'a'..'z':nIndex:=Byte(strEnc[i])-Byte('a')+26;
|
|
'0'..'9':nIndex:=Byte(strEnc[i])-Byte('0')+52;
|
|
'+':nIndex:=62;
|
|
'-':nIndex:=63;
|
|
else Exit;
|
|
end;
|
|
if (i<(nEncLenMax-1)) then
|
|
begin
|
|
nVal:=nVal shl 6;
|
|
nVal:=nVal or nIndex;
|
|
end else
|
|
begin
|
|
nVal:=nVal shl 4;
|
|
nVal:=nVal or (nIndex shr 2);
|
|
end;
|
|
end;
|
|
Result:=True;
|
|
end;
|
|
|
|
procedure loadInlFile(MapSym:TMapSym;Const fname:RawByteString);
|
|
Var
|
|
List:TStringList;
|
|
i,p:SizeInt;
|
|
S,name,sid:RawByteString;
|
|
nid:QWORD;
|
|
begin
|
|
nid:=0;
|
|
List:=TStringList.Create;
|
|
List.LoadFromFile(fname);
|
|
For i:=0 to List.Count-1 do
|
|
begin
|
|
S:=List.Strings[i];
|
|
p:=Pos('(',S);
|
|
if (p<>0) then S:=copy(s,p+1,Length(s)-p);
|
|
if (s[Length(s)]=')') then SetLength(s,Length(s)-1);
|
|
p:=Pos(',',S);
|
|
if (p<>0) then
|
|
begin
|
|
name:=copy(s,1,p-1);
|
|
sid:=copy(s,p+1,Length(s)-p);
|
|
if (sid[Length(sid)]='"') then SetLength(sid,Length(sid)-1);
|
|
if (sid[1]='"') then sid:=copy(sid,2,Length(sid)-1);
|
|
if not DecodeValue64(PChar(sid),Length(sid),nid) then
|
|
begin
|
|
Writeln('Error decode with:',sid);
|
|
Continue;
|
|
end;
|
|
if (name<>'') then
|
|
begin
|
|
if ps4_nid_hash(pchar(name))<>nid then
|
|
begin
|
|
Writeln('Error: nid hash check:',nid,'<>',ps4_nid_hash(pchar(name)));
|
|
end;
|
|
if MapSym.TryGetValue(nid,s) and (s<>name) then
|
|
begin
|
|
Writeln('Error: nid hash collision:',nid,':',s,'<>',name);
|
|
end else
|
|
MapSym.Insert(nid,name);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
FreeAndNil(List);
|
|
end;
|
|
|
|
procedure loadTxtFile(MapSym:TMapSym;Const fname:RawByteString);
|
|
Var
|
|
List:TStringList;
|
|
i:SizeInt;
|
|
name,s:RawByteString;
|
|
nid:QWORD;
|
|
begin
|
|
nid:=0;
|
|
List:=TStringList.Create;
|
|
List.LoadFromFile(fname);
|
|
For i:=0 to List.Count-1 do
|
|
begin
|
|
name:=Trim(List.Strings[i]);
|
|
if (name<>'') then
|
|
begin
|
|
nid:=ps4_nid_hash(pchar(name));
|
|
if MapSym.TryGetValue(nid,s) and (s<>name) then
|
|
begin
|
|
Writeln('Error: nid hash collision:',nid,':',s,'<>',name);
|
|
end else
|
|
MapSym.Insert(nid,name);
|
|
end;
|
|
end;
|
|
FreeAndNil(List);
|
|
end;
|
|
|
|
Var
|
|
MapSym:TMapSym;
|
|
|
|
Const
|
|
prolog1='unit ps4libdoc;'#$0D#$0A#$0D#$0A+
|
|
'{$mode objfpc}{$H+}'#$0D#$0A#$0D#$0A+
|
|
'{$WARNINGS OFF}'#$0D#$0A#$0D#$0A+
|
|
'interface'#$0D#$0A#$0D#$0A+
|
|
'Function GetFunctName(N:QWORD):PChar;'#$0D#$0A#$0D#$0A+
|
|
'implementation'#$0D#$0A#$0D#$0A+
|
|
|
|
'type'#$0D#$0A+
|
|
' TFunctData=packed record'#$0D#$0A+
|
|
' i:QWORD;'#$0D#$0A+
|
|
' n:PChar;'#$0D#$0A+
|
|
' end;'#$0D#$0A#$0D#$0A+
|
|
|
|
'var'#$0D#$0A+
|
|
' FunctData:array[0..';
|
|
|
|
prolog2='] of TFunctData=('#$0D#$0A;
|
|
|
|
ep_func=' );'#$0D#$0A#$0D#$0A+
|
|
'Function GetFunctName(N:QWORD):PChar;'#$0D#$0A+
|
|
'Var'#$0D#$0A+
|
|
' l,r,m:SizeInt;'#$0D#$0A+
|
|
'begin'#$0D#$0A+
|
|
' Result:='#$27'Unknow'#$27';'#$0D#$0A+
|
|
' l:=0;'#$0D#$0A+
|
|
' r:=Length(FunctData);'#$0D#$0A+
|
|
' while (l<r) do'#$0D#$0A+
|
|
' begin'#$0D#$0A+
|
|
' m:=l+(r-l) div 2;'#$0D#$0A+
|
|
' if (FunctData[m].i=N) then Exit(FunctData[m].n);'#$0D#$0A+
|
|
' if (FunctData[m].i>N) then'#$0D#$0A+
|
|
' begin'#$0D#$0A+
|
|
' r:=m;'#$0D#$0A+
|
|
' end else'#$0D#$0A+
|
|
' begin'#$0D#$0A+
|
|
' l:=m+1;'#$0D#$0A+
|
|
' end;'#$0D#$0A+
|
|
' end;'#$0D#$0A+
|
|
'end;'#$0D#$0A#$0D#$0A+
|
|
'end.'#$0D#$0A;
|
|
|
|
Procedure SaveToPas(Const FName:RawByteString);
|
|
Var
|
|
F:Thandle;
|
|
|
|
SymIter:TMapSym.TIterator;
|
|
i,_id:QWORD;
|
|
_name:RawByteString;
|
|
begin
|
|
F:=FileCreate(FName);
|
|
FileWrite(F,PChar(prolog1)^,Length(prolog1));
|
|
|
|
_name:=IntToStr(MapSym.Size-1);
|
|
FileWrite(F,PChar(_name)^,Length(_name));
|
|
|
|
FileWrite(F,PChar(prolog2)^,Length(prolog2));
|
|
|
|
i:=0;
|
|
SymIter:=MapSym.Min;
|
|
if (SymIter<>nil) then
|
|
begin
|
|
repeat
|
|
Inc(i);
|
|
|
|
_id :=SymIter.Key;
|
|
_name:=SymIter.Value;
|
|
_name:=' (i:$'+HexStr(_id,16)+';n:'#$27+_name+#$27')';
|
|
if (i=MapSym.Size) then
|
|
_name:=_name+#$0D#$0A
|
|
else
|
|
_name:=_name+','#$0D#$0A;
|
|
|
|
FileWrite(F,PChar(_name)^,Length(_name));
|
|
until (not SymIter.Next);
|
|
FreeAndNil(SymIter);
|
|
end;
|
|
|
|
FileWrite(F,PChar(ep_func)^,Length(ep_func));
|
|
FileClose(F);
|
|
end;
|
|
|
|
var
|
|
i,n:Integer;
|
|
|
|
begin
|
|
DefaultSystemCodePage:=CP_UTF8;
|
|
DefaultUnicodeCodePage:=CP_UTF8;
|
|
DefaultFileSystemCodePage:=CP_UTF8;
|
|
DefaultRTLFileSystemCodePage:=CP_UTF8;
|
|
UTF8CompareLocale:=CP_UTF8;
|
|
|
|
MapSym:=TMapSym.Create;
|
|
|
|
if (ParamCount=0) then
|
|
begin
|
|
Writeln('Build names base to ps');
|
|
Writeln(' Parameters:');
|
|
Writeln(' -inl <name> //inl file name');
|
|
Writeln(' -txt <name> //txt file name');
|
|
Exit;
|
|
end;
|
|
|
|
n:=-1;
|
|
For i:=1 to ParamCount do
|
|
begin
|
|
case LowerCase(ParamStr(i)) of
|
|
'-inl':n:=0;
|
|
'-txt':n:=1;
|
|
else
|
|
if (n<>-1) then
|
|
begin
|
|
Case n of
|
|
0:begin
|
|
if FileExists(ParamStr(i)) then
|
|
loadInlFile(MapSym,ParamStr(i));
|
|
end;
|
|
1:begin
|
|
if FileExists(ParamStr(i)) then
|
|
loadTxtFile(MapSym,ParamStr(i));
|
|
end;
|
|
end;
|
|
n:=-1;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
//-txt sceKernelDlsym.txt -txt list_from_sdk.txt -txt ps4_names.txt -txt known_names.txt
|
|
|
|
Writeln('Load is Fin');
|
|
SaveToPas('ps4libdoc.pas');
|
|
Writeln('Save is Fin');
|
|
|
|
readln;
|
|
end.
|
|
|