Да действительно с PWI .ехе сильно похож на наш, только его там никто не запаковывал. Отлично олька подсоединяется только что нашел ВА = E5B2A4 и GA = E5BA4C структура перса BA+1C+34+4CC(ХР перса)
Очень сильно похож. Пытаюсь найти распаковщик для нашего .ехе, чтобы сравнить с ПВИ и найти разницу байтов, которые отвечают за защиту от дебагеров.
unit uCommon;
interface
uses
windows, classes, sysutils, forms, inifiles, dllClient;
type
TIdNames = class
private
function GetIDs(index: integer): dword;
procedure SetIDs(index: integer; const Value: dword);
function GetNames(index: integer): string;
procedure SetNames(index: integer; const Value: string);
function GetCount: Integer;
function GetAddr(index: integer): dword;
procedure SetAddr(index: integer; const Value: dword);
function GetParams(index: integer): TStringList;
protected
public
IdList: TStringList;
NamesList: TStringList;
AddrList: TStringList;
ParamsList: TList;
constructor Create(const FileName: String = ''); dynamic;
destructor Destroy; override;
function Add(id: dword; name: string; addr: dword): integer;
procedure Delete(index: integer);
procedure Clear;
function IndexOfByID(id: dword): Integer;
function IndexOfByName(name: string): Integer;
function IndexOfByPartialName(partial_name: string): Integer;
function IdByName(name: string): dword;
function IdByParialName(partial_name: string): dword;
function NameById(id: dword): string;
property IDs[index: integer]: dword read GetIDs write SetIDs;
property Names[index: integer]: string read GetNames write SetNames;
property Addr[index: integer]: dword read GetAddr write SetAddr;
property Params[index: integer]: TStringList read GetParams;
//published
property Count: Integer read GetCount;
end;
var
fExit: Boolean = False;
hWindow : THandle = 0;
// WindowID : THandle = 0;
// processID : THandle = 0;
implementation
{ TIdNames }
constructor TIdNames.Create(const FileName: String = '');
var
i: Integer;
ini: TMemIniFile;
begin
IdList := TStringList.Create;
NamesList := TStringList.Create;
AddrList := TStringList.Create;
ParamsList := TList.Create;
if FileExists(FileName) then
begin
ini := TMemIniFile.Create(FileName);
ini.ReadSection('idnames', IdList);
for I := 0 to IdList.Count - 1 do
NamesList.Add(ini.ReadString('idnames', IdList[i], ''));
ini.Free;
end;
end;
destructor TIdNames.Destroy;
begin
//Clear;
IdList.Free; //IdList := nil;
NamesList.Free; //NamesList := nil;
AddrList.Free; //AddrList := nil;
ParamsList.Free; //ParamsList := nil;
// inherited Destroy;
end;
procedure TIdNames.Clear;
begin
while Count > 0 do
delete(0);
end;
function TIdNames.Add(id: dword; name: string; addr: dword): integer;
begin
IdList.Add(IntToStr(id));
AddrList.Add(IntToStr(addr));
ParamsList.Add(TList.Create);
result := NamesList.Add(name);
end;
procedure TIdNames.Delete(index: integer);
begin
if (index >= 0) and (index < count) then
begin
IdList.delete(index);
NamesList.delete(index);
AddrList.delete(index);
TList(ParamsList[index]).Clear;
ParamsList.delete(index);
end;
end;
function TIdNames.GetAddr(index: integer): dword;
begin
if (index >= 0) and (index < count) then
result := StrToInt(AddrList[index])
else
result := 0;
end;
function TIdNames.GetCount: Integer;
begin
if IdList <> nil then
result := IdList.Count
else
result := 0;
end;
function TIdNames.GetIDs(index: integer): dword;
begin
if (index >= 0) and (index < count) then
result := StrToInt(IdList[index])
else
result := 0;
end;
function TIdNames.GetNames(index: integer): string;
begin
if (index >= 0) and (index < count) then
result := NamesList[index]
else
result := '';
end;
function TIdNames.GetParams(index: integer): TStringList;
begin
if (index >= 0) and (index < count) then
result := TStringList(ParamsList[index])
else
result := nil;
end;
function TIdNames.IdByName(name: string): dword;
var
i, idx: integer;
begin
name := UpperCase(Trim(name));
idx := -1;
for I := 0 to NamesList.Count-1 do
if UpperCase(Trim(NamesList[i])) = name then
begin
idx := i;
break;
end;
if idx >= 0 then
result := IDs[idx]
else
result := MaxWord;
end;
function TIdNames.IdByParialName(partial_name: string): dword;
var
i, idx: integer;
begin
partial_name := UpperCase(Trim(partial_name));
idx := -1;
for I := 0 to NamesList.Count-1 do
if Pos(partial_name, UpperCase(Trim(NamesList[i]))) = 1 then
begin
idx := i;
break;
end;
if idx >= 0 then
result := IDs[idx]
else
result := MaxWord;
end;
function TIdNames.IndexOfByID(id: dword): Integer;
var
sId: string;
begin
sId := IntToStr(id);
result := IdList.IndexOf(sId);
end;
function TIdNames.IndexOfByName(name: string): Integer;
var
i: integer;
begin
name := UpperCase(Trim(name));
result := -1;
for I := 0 to NamesList.Count-1 do
if UpperCase(Trim(NamesList[i])) = name then
begin
result := i;
break;
end;
end;
function TIdNames.IndexOfByPartialName(partial_name: string): Integer;
var
i: integer;
begin
partial_name := UpperCase(Trim(partial_name));
result := -1;
for I := 0 to NamesList.Count-1 do
if Pos(partial_name, UpperCase(Trim(NamesList[i]))) = 1 then
begin
result := i;
break;
end;
end;
function TIdNames.NameById(id: dword): string;
var
idx: integer;
sId: string;
begin
sId := IntToStr(id);
idx := IdList.IndexOf(sId);
if idx >= 0 then
result := NamesList[idx]
else
result := '';
end;
procedure TIdNames.SetAddr(index: integer; const Value: dword);
begin
if (index >= 0) and (index < IdList.count) then
AddrList[index] := IntToStr(Value);
end;
procedure TIdNames.SetIDs(index: integer; const Value: dword);
begin
if (index >= 0) and (index < IdList.count) then
IdList[index] := IntToStr(Value);
end;
procedure TIdNames.SetNames(index: integer; const Value: string);
begin
if (index >= 0) and (index < count) then
NamesList[index] := Value;
end;
end.
В этом коде есть функция:
Код:
function TIdNames.Add(id: dword; name: string; addr: dword): integer;
begin
IdList.Add(IntToStr(id));
AddrList.Add(IntToStr(addr));
ParamsList.Add(TList.Create);
result := NamesList.Add(name);
end;
Вот в этой строчке идет добавление скиллов
ParamsList.Add(TList.Create);
Сколько добавилось скилов, столько и пишет
[Ссылки могут видеть только зарегистрированные пользователи. ]
Меня смущает TList.Create, что то здесь не так. Прочитал документацию вроде все правильно. А когда подключаешь к проекту ReportMemoryLeaksOnShutdown := True; утечка памяти, вываливается окно выше.
И не совсем понимаю, как работают эти 4 строчки. Если убрать совсем ParamsList.Add(TList.Create); перестают работать скиллы, хотя список вываливается, его видно, можно выбрать(Походу индексации нет)
Я правильно понимаю, IdList и AddrList добавляются с начало в TList, а потом TList добавляется ParamsList? Кто может объяснить, как работают эти 4 строчки?
Вот тест сделал, что бы было наглядно в чем заключается проблема[Ссылки могут видеть только зарегистрированные пользователи. ]
Последний раз редактировалось diagnost; 19.07.2016 в 00:19.
Вот 4 списка. Первые три - строковые. Последний - с указателями.
...
IdList.Add(IntToStr(id));
AddrList.Add(IntToStr(addr));
ParamsList.Add(TList.Create);
result := NamesList.Add(name);
Эти команды добавляют (в конец) для первых двух списков текст с айдишником и адресом.
Третья создает список для параметров. Тут утечка, если этот лист никто не удаляет.
Четвертая - добавляет имя и заодно пользуется возвращаемым значением .Add чтобы вернуть нумер последнего индекса.
Теперь смотрим на
procedure TIdNames.Delete(index: integer);
...
TList(ParamsList[index]).Clear;
...
Это - очистка списка, а не удаление. Создали, но не удалили. По идее, должно быть
TList(ParamsList[index]).Free;
Вот спасибо!!! Выручил час бота допилим!
Вот моя благодарность потраченное время на разбор[Ссылки могут видеть только зарегистрированные пользователи. ]
На выходных буду переделывать интерфейс, не все параметры правильно сохраняются(в основном касается вкладки Башни будды)
Вот 4 списка. Первые три - строковые. Последний - с указателями.
...
IdList.Add(IntToStr(id));
AddrList.Add(IntToStr(addr));
ParamsList.Add(TList.Create);
result := NamesList.Add(name);
Эти команды добавляют (в конец) для первых двух списков текст с айдишником и адресом.
Третья создает список для параметров. Тут утечка, если этот лист никто не удаляет.
Четвертая - добавляет имя и заодно пользуется возвращаемым значением .Add чтобы вернуть нумер последнего индекса.
Теперь смотрим на
procedure TIdNames.Delete(index: integer);
...
TList(ParamsList[index]).Clear;
...
Это - очистка списка, а не удаление. Создали, но не удалили. По идее, должно быть
TList(ParamsList[index]).Free;
В общем в вот так сделал, вроде пока работает(ParamsList совсем убрал):
Код:
unit uCommon;
interface
uses
windows, classes, sysutils, inifiles, ClientPerem;
type
TIdNames = class(TObject)
private
function GetIDs(index: integer): dword;
procedure SetIDs(index: integer; const Value: dword);
function GetNames(index: integer): string;
procedure SetNames(index: integer; const Value: string);
function GetCount: Integer;
function GetAddr(index: integer): dword;
procedure SetAddr(index: integer; const Value: dword);
protected
public
IdList: TStringList;
NamesList: TStringList;
AddrList: TStringList;
constructor Create(const FileName: String = ''); dynamic;
destructor Destroy; override;
function Add(id: dword; name: string; addr: dword): integer;
procedure Delete(index: integer);
procedure Clear;
function IndexOfByID(id: dword): Integer;
function IndexOfByName(name: string): Integer;
function IndexOfByPartialName(partial_name: string): Integer;
function IdByName(name: string): dword;
function IdByParialName(partial_name: string): dword;
function NameById(id: dword): string;
property IDs[index: integer]: dword read GetIDs write SetIDs;
property Names[index: integer]: string read GetNames write SetNames;
property Addr[index: integer]: dword read GetAddr write SetAddr;
property Count: Integer read GetCount;
end;
implementation
{ TIdNames }
constructor TIdNames.Create(const FileName: String = '');
var
i: Integer;
ini: TMemIniFile;
begin
IdList := TStringList.Create;
NamesList := TStringList.Create;
AddrList := TStringList.Create;
if FileExists(FileName) then
begin
ini := TMemIniFile.Create(FileName);
ini.ReadSection('idnames', IdList);
for I := 0 to IdList.Count - 1 do
NamesList.Add(ini.ReadString('idnames', IdList[i], ''));
ini.Free;
end;
end;
destructor TIdNames.Destroy;
begin
//Clear;
FreeAndNil(IdList);//IdList.Free; //IdList := nil;
FreeAndNil(NamesList);//NamesList.Free; //NamesList := nil;
FreeAndNil(AddrList);//AddrList.Free; //AddrList := nil;
// inherited Destroy;
end;
procedure TIdNames.Clear;
begin
while Count > 0 do
delete(0);
end;
function TIdNames.Add(id: dword; name: string; addr: dword): integer;
begin
IdList.Add(IntToStr(id));
AddrList.Add(IntToStr(addr));
result := NamesList.Add(name);
end;
procedure TIdNames.Delete(index: integer);
begin
if (index >= 0) and (index < count) then
begin
IdList.delete(index);
NamesList.delete(index);
AddrList.delete(index);
end;
end;
function TIdNames.GetAddr(index: integer): dword;
begin
if (index >= 0) and (index < count) then
result := StrToInt64Def(AddrList[index], MaxDword)
else
result := MaxDword;
end;
function TIdNames.GetCount: Integer;
begin
if IdList <> nil then
result := IdList.Count
else
result := 0;
end;
function TIdNames.GetIDs(index: integer): dword;
begin
if (index >= 0) and (index < count) then
result := StrToInt64Def(IdList[index], MaxDword)
else
result := MaxDword;
end;
function TIdNames.GetNames(index: integer): string;
begin
if (index >= 0) and (index < count) then
result := NamesList[index]
else
result := '';
end;
function TIdNames.IdByName(name: string): dword;
var
i, idx: integer;
begin
name := UpperCase(Trim(name));
idx := -1;
for I := 0 to NamesList.Count-1 do
if UpperCase(Trim(NamesList[i])) = name then
begin
idx := i;
break;
end;
if idx >= 0 then
result := IDs[idx]
else
result := MaxWord;
end;
function TIdNames.IdByParialName(partial_name: string): dword;
var
i, idx: integer;
begin
partial_name := UpperCase(Trim(partial_name));
idx := -1;
for I := 0 to NamesList.Count-1 do
if Pos(partial_name, UpperCase(Trim(NamesList[i]))) = 1 then
begin
idx := i;
break;
end;
if idx >= 0 then
result := IDs[idx]
else
result := MaxWord;
end;
function TIdNames.IndexOfByID(id: dword): Integer;
var
sId: string;
begin
sId := IntToStr(id);
result := IdList.IndexOf(sId);
end;
function TIdNames.IndexOfByName(name: string): Integer;
var
i: integer;
begin
name := UpperCase(Trim(name));
result := -1;
for I := 0 to NamesList.Count-1 do
if UpperCase(Trim(NamesList[i])) = name then
begin
result := i;
break;
end;
end;
function TIdNames.IndexOfByPartialName(partial_name: string): Integer;
var
i: integer;
begin
partial_name := UpperCase(Trim(partial_name));
result := -1;
for I := 0 to NamesList.Count-1 do
if Pos(partial_name, UpperCase(Trim(NamesList[i]))) = 1 then
begin
result := i;
break;
end;
end;
function TIdNames.NameById(id: dword): string;
var
idx: integer;
sId: string;
begin
sId := IntToStr(id);
idx := IdList.IndexOf(sId);
if idx >= 0 then
result := NamesList[idx]
else
result := '';
end;
procedure TIdNames.SetAddr(index: integer; const Value: dword);
begin
if (index >= 0) and (index < IdList.count) then
AddrList[index] := IntToStr(Value);
end;
procedure TIdNames.SetIDs(index: integer; const Value: dword);
begin
if (index >= 0) and (index < IdList.count) then
IdList[index] := IntToStr(Value);
end;
procedure TIdNames.SetNames(index: integer; const Value: string);
begin
if (index >= 0) and (index < count) then
NamesList[index] := Value;
end;
end.
Добавлено через 3 минуты
Для удобства вынес все офзеты в отдельный лист, выглядит вот так примерно:
исходники проекта открытые, бери и дорабатывай как тебе нужно.
________________ Продаю приват читы для AION Absolute, desteny 3.5, Legend, Cataclysm, Ru, EU, NA Продаю многооконку на R2 Пишу читы на заказ под любые игры. Предложения в ЛС. Все мои читы/программы/статьи тут:http://zhyk.ru/forum/showpost.php?p=38501&postcount=21