сделал кодировку как вы и сказали... так же ничего не пишет в поле логина, но зато пока эксперементировал с типами клиент бывало вылетал, следовательно данные пердаются, но поле все равно не заполняется, вот переделанный код
Код:
var
Form1: TForm1;
rw: Cardinal;
hProcess: Dword;
xByte: ByteArray;
prov:array[0..255] of WideChar;
implementation
{$R *.dfm}
function Read_32(Addr: Dword): Dword;
var value: Dword;
begin
ReadProcessMemory(hProcess, ptr(addr), @value, sizeof(value), rw);
result := value;
end;
function WinStruct(WinName: AnsiString): Dword;
var
arr, addr, next, res: Dword;
mass: array[1..20] of Char;
name: AnsiString;
i:integer;
begin
arr := Read_32(GA);
arr := Read_32(arr + $18);
arr := Read_32(arr + $08);
addr := Read_32(arr + $AC);
while (addr <> null) do
begin
next := Read_32(addr);
addr := Read_32(addr+$08);
res := addr;
addr := Read_32(addr+$4C);
ReadProcessMemory(hProcess, ptr(addr), @mass, sizeof(mass), rw);
i:=1;
while mass[i]<>'' do
begin
name:=name+mass[i];
inc(i);
end;
if (name = WinName) then
begin
result := res;
exit;
end;
addr := next;
end;
addr := Read_32(arr+$8C);
while (addr <> null) do
begin
next := Read_32(addr);
addr := Read_32(addr+$08);
res := addr;
addr := Read_32(addr+$4C);
ReadProcessMemory(hProcess, ptr(addr), @mass, sizeof(mass), rw);
i:=1;
while mass[i]<>'' do
begin
name:=name+mass[i];
inc(i);
end;
if (name = WinName) then
begin
result := res;
exit;
end;
addr := next;
end;
result := 0;
end;
function CtrlEditTextPtr(winstruct: Dword; nomctrl: integer): Dword;
var
addr: Dword;
i: integer;
begin
addr := Read_32(winstruct + $1C8);
for i:=1 to nomctrl do
addr := Read_32(addr + $04);
addr := Read_32(addr + $08);
result := addr + $13FC;
end;
function WriteLogin(login: String): pointer;
var
ThreadAddr: pointer;
begin
StringToWideChar(login, prov, Length(login)+1);
ThreadAddr := VirtualAllocEx(hProcess, nil, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, ThreadAddr, @prov, sizeof(prov), rw);
result:=ThreadAddr;
end;
procedure connect;
var
PID: dword;
WID: Thandle;
begin
WID:=FindWindow(nil,'Perfect World');
GetWindowThreadProcessId(WID, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
connect;
if hProcess<>0 then
begin
WriteProcessMemory(hProcess, ptr(CtrlEditTextPtr(WinStruct('Win_Login'), 8)), WriteLogin('proba'), sizeof(prov),rw);
end
else
showmessage('îøèáêà');
end;
голова кругом уже
Последний раз редактировалось vladoscom93; 23.07.2012 в 23:09.
Такие вот моменты..
prov:array[0..255] of WideChar;
WideChar - двухбайтный по размеру, итого 256*2=512
Вы выделяете 256 байт
VirtualAllocEx(hProcess, nil, 256, MEM_COMMIT, PAGE_READWRITE);
и помоему записываете 512, проверьте какое число получается из sizeof(prov).
Так же попробуйте заполнять prov нулями перед этим..
StringToWideChar(login, prov, Length(login)+1);
чтобы всё кроме логина было нулями.
Так же после ThreadAddr := VirtualAllocEx(hPro...
проверьте ThreadAddr на NILL, так как VirtualAllocEx почему то время от времени не выделяет память а возвращает ноль, а дальше идёт запись по нулевому адресу в данные клиента. Часто косяки бывают из-за отсутствия проверки, и у меня такое было, и у других замечал.
Блин, хоть делфи устанавливать))
Ещё попробуйте вместо result:=ThreadAddr;
Создать глобальную переменную DWORD Addr, и возвращать в неё значение ThreadAddr, а затем уже использовать в WriteProcess, так, чтобы записать именно значение адреса а не сам текст, почему то мне думается, что у вас пишется не адрес а данные текста. К тому же вот что проверьте
WriteProcessMemory(hProcess, ptr(CtrlEditTextPtr(WinStruct('Win_Login'), 8)), WriteLogin('proba'), sizeof(prov),rw);
сколько байт возвращает sizeof(prov), нам нужно 4 байта адреса, а если sizeof(prov) возвращает размер всего массива, то тогда получается так, что в структуру контрола пишется не только адрес, а дофига байт, перекрывая данные контрола. Ещё раз замечу, нам нужно записать здесь не сам текст а АДРЕС текста - 4 байта.
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 24.07.2012 в 19:10.
prov полностью обнуляю размеры подправил... есть одно но вы пишете Addr присвоить ThreadAddr этого не получится так как ThreadAddr имеет тип pointer или вы имели ввиду сделать так:
Нет нет, именно значение addr := ThreadAddr, как вот только тип преобразовать..
а read_32(ThreadAddr) вроде как вернёт первые 4 байта текста, который мы заинжектили)
Скачал делфи, щас буду экспериментировать, если конечно установится и не начнёт конфликтовать с с++, как оно было когдато давно, после чего я его снёс)))
Вот, всё работает
Код:
var
Form1: TForm1;
rw: Cardinal;
hProcess: Dword;
xByte: Array of byte;
prov:array[0..255] of WideChar;
implementation
{$R *.dfm}
function Read_32(Addr: Dword): Dword;
var value: Dword;
begin
ReadProcessMemory(hProcess, ptr(addr), @value, sizeof(value), rw);
result := value;
end;
function WinStruct(WinName: AnsiString): Dword;
var
arr, addr, next, res: Dword;
mass: array[1..20] of Char;
name: AnsiString;
i:integer;
begin
arr := Read_32($00A57ACC);
arr := Read_32(arr + $18);
arr := Read_32(arr + $08);
addr := Read_32(arr + $AC);
while (addr <> null) do
begin
next := Read_32(addr);
addr := Read_32(addr+$08);
res := addr;
addr := Read_32(addr+$4C);
ReadProcessMemory(hProcess, ptr(addr), @mass, sizeof(mass), rw);
i:=1;
while mass[i]<>'' do
begin
name:=name+mass[i];
inc(i);
end;
if (name = WinName) then
begin
result := res;
exit;
end;
addr := next;
end;
addr := Read_32(arr+$8C);
while (addr <> null) do
begin
next := Read_32(addr);
addr := Read_32(addr+$08);
res := addr;
addr := Read_32(addr+$4C);
ReadProcessMemory(hProcess, ptr(addr), @mass, sizeof(mass), rw);
i:=1;
while mass[i]<>'' do
begin
name:=name+mass[i];
inc(i);
end;
if (name = WinName) then
begin
result := res;
exit;
end;
addr := next;
end;
result := 0;
end;
function CtrlEditTextPtr(winstruct: Dword; nomctrl: integer): Dword;
var
addr: Dword;
i: integer;
begin
addr := Read_32(winstruct + $1C8);
for i:=1 to nomctrl do
addr := Read_32(addr + $04);
addr := Read_32(addr + $08);
result := addr + $13FC;
end;
function WriteLogin(login: String): dword;
var
ThreadAddr: pointer;
begin
StringToWideChar(login, prov, Length(login)+1);
ThreadAddr := VirtualAllocEx(hProcess, nil, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, ThreadAddr, @prov, sizeof(prov), rw);
result:=dword(ThreadAddr);
end;
procedure connect;
var
PID: dword;
WID: Thandle;
begin
WID:=FindWindow(nil,'Perfect World');
GetWindowThreadProcessId(WID, @PID);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID);
end;
procedure TForm1.Button1Click(Sender: TObject);
var addr, textptr: dword;
begin
connect;
if hProcess<>0 then
begin
addr:=WriteLogin('proba');
textptr:=CtrlEditTextPtr(WinStruct('Win_Login'), 8);
WriteProcessMemory(hProcess, ptr(textptr), @addr, 4,rw);
end
else
showmessage('хз');
end;
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 24.07.2012 в 20:15.
ппц... рука лицо и все это из-за этой строчки result:=dword(ThreadAddr); спасибо огромное за помощь теперь буду разбираться с чекбоксом усиленно и нажатием кнопок))
ппц... рука лицо и все это из-за этой строчки result:=dword(ThreadAddr); спасибо огромное за помощь теперь буду разбираться с чекбоксом усиленно и нажатием кнопок))
Секунду, чего-то вылетать стало у меня.. где то косяк
Чего-то не пойму в чём мистика, то пишет, то крашится..
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 24.07.2012 в 21:43.
Для просмотра ссылок или изображений в подписях, у Вас должно быть не менее 10 сообщение(ий). Сейчас у Вас 0 сообщение(ий). - Совершенный автологин для Perfect World [RUOFF, PWI, Фришек 1.4.4 - 1.4.5]
--------------------------------------------
Для просмотра ссылок или изображений в подписях, у Вас должно быть не менее 10 сообщение(ий). Сейчас у Вас 0 сообщение(ий). - Патч на Горны, Красный (да и любой) чат, Анфриз, Бесконечный зум, Моментальный разгон на полете для RUOFF, PWI и прочих 1.4.6 и фришек 1.4.4, 1.4.5.
--------------------------------------------
Для просмотра ссылок или изображений в подписях, у Вас должно быть не менее 10 сообщение(ий). Сейчас у Вас 0 сообщение(ий). - патчер для серверов 1.4.5 и 1.4.4 работающий с включенной игрой.
--------------------------------------------
Извиняюсь за некропост, но все же.
в функции function WinStruct(WinName: AnsiString): Dword;
переменную name нужно обнулять после
Код:
if (name = WinName) then
begin
result := res;
exit;
end;
Так как в нее постоянно прибавлялось новое значение и ее текст становился только больше, поэтому поиск был бы неудавшимся.
и вот сделал , точнее переделал функцию для выбора контрола. может кому понадобится
Код:
function StrActCtrl(winstruct: Dword; nomctrl: integer): Dword;
var
addr: Dword;
i: integer;
begin
addr := Read_32(winstruct + $1C8);
for i:=1 to nomctrl do
addr := Read_32(addr + $4);
addr := Read_32(addr + $8);
addr := Read_32(addr + $1C);
result :=addr;
end;
вызывается вот так
StrActCtrl(WinStruct('Win_Manage2'), 1);
________________
Хотите как то отблагодарить за помощь?
Не стесняйтесь нажимайте "Спасибо" Для просмотра ссылок или изображений в подписях, у Вас должно быть не менее 10 сообщение(ий). Сейчас у Вас 0 сообщение(ий).
Делаю программы на заказ, по всем вопросам в скайп: Ginrey2
Последний раз редактировалось Ginrey; 16.06.2013 в 02:50.
Откуда взялись цифры 8 и 10? Как прочитать с клиента?(Обидно то, что все нашел, разобрался как читать, нашел все офзеты, инжекты, а спросить не у кого. Если знаете, напишите цепочку офзетов до этих цифр или как рассчитать?). Как читается в программе №20? ([Ссылки могут видеть только зарегистрированные пользователи. ].)
Последний раз редактировалось diagnost; 30.05.2016 в 22:34.
Откуда взялись цифры 8 и 10? Как прочитать с клиента?(Обидно то, что все нашел, разобрался как читать, нашел все офзеты, инжекты, а спросить не у кого. Если знаете, напишите цепочку офзетов до этих цифр или как рассчитать?). Как читается в программе №20? ([Ссылки могут видеть только зарегистрированные пользователи. ].)