Rus. server

12/07/2009 10:39 AlexGD#841
Добрался до перемещений перса.

Спасибо мужику за адреса инжектов.

Вот код исправленный и дополненный:

Code:
  Type
  PParams = ^TParams;
  TParams = packed record
    Param1: DWORD;
    Param2: DWORD;
    Param3: single;
    Param4: single;
    Param5: single;
    Param6: byte;
    Param7: Cardinal;
  end;

    aBaseAddress          = $009771BC;      //base address for getting info

...
  aBasePointer := getDWORD(aBaseAddress);
...

    PW_Base_Call          = $00976B1C;    //base address for injections
    PW_Walk_Call1         = $00461FD0;    //addresses for walk injection
    PW_Walk_Call2         = $00465AB0;    //addresses for walk injection
    PW_Walk_Call3         = $004623D0;    //addresses for walk injection

procedure WalkCall(aPParams:PParams); Stdcall;
var
  Address1: pointer;
  Address2: pointer;
  Address3: pointer;
  x, y, z : single;
  flying  : Cardinal;
begin
  Address1 := pointer(PW_Walk_Call1);
  Address2 := pointer(PW_Walk_Call2);
  Address3 := pointer(PW_Walk_Call3);
  x := aPParams^.Param3;
  y := aPParams^.Param4;
  z := aPParams^.Param5;
  flying := aPParams^.Param7;

  asm
    pushad
      mov eax, dword ptr [PW_Base_Call]
      mov eax, dword ptr [eax+$1C]
      mov esi, dword ptr [eax+$20]
      mov ecx, dword ptr [esi+$C10]
      push 1
      call Address1

      mov edi, eax
      lea eax, dword ptr [esp+$0C]
      push eax
      push flying
      mov ecx, edi
      call Address2

      mov ecx, dword ptr [esi+$C10]
      push 0
      push 1
      push edi
      push 1
      call Address3

      mov eax, dword ptr [PW_Base_Call]
      mov eax, dword ptr [eax+$1C]
      mov eax, dword ptr [eax+$20]
      mov eax, dword ptr [eax+$C10]
      mov eax, dword ptr [eax+$30]
      mov ecx, dword ptr [eax+$4]
      mov eax, x
      mov dword ptr[ecx+$20], eax
      mov eax, z
      mov dword ptr[ecx+$24], eax
      mov eax, y
      mov dword ptr[ecx+$28], eax
    popad
  end;
end;

procedure TaPWT.WalkTo(x, y, z: single);
var
  aParams : TParams;
  aParamsSize: DWORD;
  aPlayer: TaPlayer;
begin
  aPlayer        := getPlayer(getDWORD(aBasePointer + $20));
  aParams.Param3 := (x - 400) * 10;
  aParams.Param4 := (y - 550) * 10;
  aParams.Param5 := z * 10;
  aParams.Param7 := aPlayer.TransportMode;
  aParamsSize := SizeOf(aParams);
  injectfunc(aProcessID, @WalkCall, @aParams, aParamsSize);
end;
7й дельфи почему-то не захотел работать с двордом в колле - пришлось вводить в ТПарамс еще и кардинал (

aPlayer.TransportMode: Cardinal. Но нужно не забывать, что на самом деле это байт(!). И получать его нужно:
result.TransportMode := getBYTE(playerPointer + $60D);

Гет функции, что я юзаю:
Code:
function TaPWT.getBYTE(aPointer: integer) : BYTE;
var
  dwReaded: DWORD;
begin
  ReadProcessMemory(aProcessID, ptr(aPointer), @result, SizeOf(result), dwReaded);
end;

function TaPWT.getWORD(aPointer: integer) : WORD;
var
  dwReaded: DWORD;
begin
  ReadProcessMemory(aProcessID, ptr(aPointer), @result, SizeOf(result), dwReaded);
end;

function TaPWT.getDWORD(aPointer: integer) : DWORD;
var
  dwReaded: DWORD;
begin
  ReadProcessMemory(aProcessID, ptr(aPointer), @result, SizeOf(result), dwReaded);
end;

function TaPWT.getFLOAT(aPointer: integer) : Single;
var
  dwReaded: DWORD;
begin
  ReadProcessMemory(aProcessID, ptr(aPointer), @result, SizeOf(result), dwReaded);
end;

function TaPWT.getSTRING16(aPointer: integer) : WideString;
var
  dwReaded: DWORD;
  buf : array[0..16] of WideChar;
begin
  ReadProcessMemory(aProcessID, ptr(aPointer), @buf, 16, dwReaded);
  result := buf;
end;

function TaPWT.getSTRING32(aPointer: integer) : WideString;
var
  dwReaded: DWORD;
  buf : array[0..32] of WideChar;
begin
  ReadProcessMemory(aProcessID, ptr(aPointer), @buf, 32, dwReaded);
  result := buf;
end;
12/07/2009 17:04 muzhig#842
AlexGD, твою помощь трудно переоценить!
Адресок инжекта копки ресов и трав кто нибудь подскажет?
12/07/2009 22:16 AlexGD#843
Quote:
Originally Posted by muzhig View Post
AlexGD, твою помощь трудно переоценить!
Адресок инжекта копки ресов и трав кто нибудь подскажет?
Тут хитрость... Нет такого инжекта. Как я понял - это тоже атака... Пока я не в курсе, потому что пишу не бота и это мне еще не надо было ) Возможно и совсем не понадобится... Хотя я еще не схавал что такое CullCall у китайцев.

Quote:
Originally Posted by muzhig View Post
ты хотел сказать
getbyte(playerPointer + $654))
Ноувэй. Мой код проверен и работает... От меня теперь ниадна птычко из ЧСлиста свалить не может :D

Вот еще раз по этому поводу...

Code:
  aBaseAddress          = $009771BC;      //base address for getting info
  aBasePointer := getDWORD(aBaseAddress);
  playerPointer := getDWORD(aBasePointer + $20);

    result.RunMode := getBYTE(playerPointer + $60C);
    case result.RunMode of
      0: result.RunModeTitle := 'Run';
      1: result.RunModeTitle := 'Walk';
    end;

    result.TransportMode := getBYTE(playerPointer + $60D);
    case result.TransportMode of
      0: result.TransportModeTitle := 'Ground';
      1: result.TransportModeTitle := 'Flying';
      2: result.TransportModeTitle := 'Swimming'; //not works :( need to be clarifyed
    end;
12/07/2009 22:20 AlexGD#844
Сейчас вот приступлю к поиску как с НПС разговаривать. Задалпался сам брошь летать )
12/08/2009 00:48 dwar#845
Ну, коль люди серьезно взялись за работу, вот код для прыжка (у него нет ограничение на кол-во сделанных прыжков) :)
Code:
  PW_Call := pointer($00470E20);
  PW_BASE_ADDR := pointer($00976B1C);
  asm
      pushad
        push  $0
        push  $C8
        push  $1
        push  $3F800000
        push  $4
        mov   esi, dword ptr [PW_BASE_ADDR]
        mov   esi, dword ptr [esi+$1C]
        mov   esi, dword ptr [esi+$20]
        mov   ecx, esi
        mov   eax, $41200000
        mov   dword ptr[ecx+$B58], $1
        mov   dword ptr[ecx+$B08], eax
        mov   dword ptr[ecx+$B60], eax
        mov   dword ptr[ecx+$AE4], $0
        mov   dword ptr[ecx+$B00], $0
        mov   dword ptr[ecx+$AFC], $0
        mov   dword ptr[ecx+$AF8], $0
        call  PW_Call
      popad
  end;
Что касается копки реса… абсолютно верно, нет отдельной функции для этого действия, достаточно вызвать простую атаку с нужным id.

А вот и разговор с НИПом (проверьте еще раз, т.к. я давно ей не пользовался, может быть, что-нибудь поменялось уже)

Code:
  PW_Call := pointer ($005AE400);
  PW_BASE_ADDR := pointer ($00976B1C);
  P1 := NPCID^.Param1 ;
    asm
        mov   edx, DWORD PTR [PW_BASE_ADDR]
        mov   ecx, P1
        push  ecx
        mov   ecx, DWORD PTR [edx+$20]
        add   ecx, $EC
        call  PW_Call
    end;
Но вот чего нет, так это функции продажи вещей… ;)
12/08/2009 02:45 AlexGD#846
Quote:
Originally Posted by dwar View Post
Ну, коль люди серьезно взялись за работу, вот код для прыжка (у него нет ограничение на кол-во сделанных прыжков) :)
[/code]
Работает! Спс!
12/08/2009 02:50 AlexGD#847
Малость пришлось попариться со списком неписей и мобов... Оказалось, что имя непися или моба аж 64 ВайдЧара... Круто завернули. Внушает...

функции getSTRING16 и getSTRING32 исчезли. Теперь я пользую:

Code:
function TaPWT.getSTRING(aPointer, length: integer) : WideString;
var
  dwReaded: DWORD;
  buf16 : array[0..16] of WideChar;
  buf32 : array[0..32] of WideChar;
  buf64 : array[0..64] of WideChar;
begin
  if length = 16 then
  begin
    ReadProcessMemory(aProcessID, ptr(aPointer), @buf16, length, dwReaded);
    result := buf16;
  end;
  if length = 32 then
  begin
    ReadProcessMemory(aProcessID, ptr(aPointer), @buf32, length, dwReaded);
    result := buf32;
  end;
  if length = 64 then
  begin
    ReadProcessMemory(aProcessID, ptr(aPointer), @buf64, length, dwReaded);
    result := buf64;
  end;
end;
Рабочая функция для получения листа мобов/неписей

Code:
function TaPWT.GetLocationMobNPC(nType: integer): TaNPCArray;
var
  aNPC: TaNPC;
  p1, p2, p3, p4, p5 : DWORD;
  i, n: integer;
begin
  SetLength(result, 768);
  n := 0;
  p1 := getDWORD(aBasePointer + $8);
  p2 := getDWORD(p1 + $24);
  p3 := getDWORD(p2 + $18);
  for i := 0 to 795 do
  begin
    p4 := getDWORD(p3 + (i * 4));
    p5 := getDWORD(p4 + $4);
    if getDWORD(p5 + $B4) = nType then //6 = Mob, 7 = NPC
    begin
      aNPC := getMobNPC(p5);
      if aNPC.ID <> 0 then
      begin
        result[n] := aNPC;
        Inc(n);
      end;
    end;
  end;
end;


function TaPWT.getMobNPC(aPointer: DWORD) : TaNPC;
var
  NamePointer : DWORD;
begin
  result.ID := getDWORD(aPointer + $11C);

  result.HPCurr := getDWORD(aPointer + $12c);
  result.HPMax  := getDWORD(aPointer + $15c);

  result.Level := getDWORD(aPointer + $124);

  NamePointer := getDWORD(aPointer + $23C);
  result.Name := getSTRING(NamePointer, 64);

  result.Location.X := (getFLOAT(aPointer + $3C) / 10) + 400;
  result.Location.Y := (getFLOAT(aPointer + $44) / 10) + 550;
  result.Location.Z := (getFLOAT(aPointer + $40) / 10);
end;
12/08/2009 03:13 AlexGD#848
Оформленный рабочий иньект разговора с НПС

Code:
    PW_Talk_Call          = $005AE400;    //address for NPC talk call insertion


procedure NPCTalkCall(aPParams:PParams); Stdcall;
var
  NPCIDParam: DWORD;
  Address1: pointer;
begin
  Address1 := pointer(PW_Talk_Call);
  NPCIDParam := aPParams^.Param1;
  asm
    pushad
      mov edx,dword ptr [PW_Base_Call]
      push NPCIDParam
      mov ecx,dword ptr [edx+$20]
      add ecx,$EC
      call Address1
    popad
  end;
end;

procedure TaPWT.TalkToNPC(NPCID: Cardinal);
var
  aParams : TParams;
begin
  aParams.Param1 := NPCID;
  InjectFunc(aProcessID, @NPCTalkCall, @aParams, SizeOf(aParams));
end;
12/08/2009 03:19 AlexGD#849
И вот началась веселуха...

Как нажать у НПС пункт "Задание"? или хотя бы 1й/2й/3й пункты...

Есть у кого идеи?
12/08/2009 06:30 AlexGD#850
Хммм... А у тебя BA какой? У меня $009771BC
12/08/2009 06:32 AlexGD#851
Кстати... Не подскажешь иньект-поинтер на бэйс-атаку? Уже 3 часа убил - не могу найти...
12/09/2009 05:19 AlexGD#852
Тут хитрая фишка... На самом деле ты нашел инжект не для атаки, а для вызова скила атаки. А это не совсем то. Насколько я понимаю - нужен инжект как будто на рес навели мышку и кликнули. Ты вот сейчас с этим для ресов мучаешься, а я для разговора с неписями )
12/09/2009 05:55 AlexGD#853
Я OllyDBG первый раз в глаза увидел неделю назад ) Сам учусь еще...
12/09/2009 08:18 dwar#854
:) вот, а если бы все готовое выкладывали, то такого бурного «исследования» никогда бы и не было… + человек, который этим занимается, естественно, набирается опыта…
Но корректировки требуются всегда, посему…
Ошибка в неправильно найденной функции. Та, что отвечает за атаку, находится чуть-чуть в другом месте, и, конечно же, одним из параметров ее является wid цели.
Относительно простой способ поиска нужных функций – поставить точки останова на определенные команды, допустим на mov eax, [976B1C]… Вот еще адреса двух case’ов: 00598B9D, 00598B76. Если в них установить брейкпоинты, то получится отследить с самого начала многие действия.

Что касается сбора реса не посредством инжекта, то здесь тоже ошибка, идущая с самых начал, когда было написано, что для этого надо выбрать действительную цель, атаковать ее, потом быстро переписать id цели на id реса и чар побежит копать (неужели такое у кого-то получалось)… Есть же массив указателей всех действий: простая атака, медитация, копка реса, следовать и т.п. Достаточно использовать нужные указатели и, ну почти просто, получится осуществить большую часть функций чара.

В экселовской таблице, на первом листе, часть адресов еще годичной давности…
12/09/2009 10:08 Sergiy76#855
Русский бот альфа версия скомпилированый [Only registered and activated users can see links. Click Here To Register...]
А это его исходный текст на С++
[Only registered and activated users can see links. Click Here To Register...]
Бот пока работает хуже MHSа, но можно переделывать, улучшить.

Вопрос - Как на С++ реализовать движение к координате?
Кто-ть может написать готовую процедуру?

Необходимо для реализации сборы лута и бега в магазин.