Перехватанный send уже не работает

Тема в разделе "WASM.NETWORKS", создана пользователем sin, 23 июл 2008.

  1. sin

    sin New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2008
    Сообщения:
    5
    Здравствуйте. У меня есть dll, которая инжектируется в процессы, но вот когда случится перехват, и длл переопределяет функцию send, тогда всё глохнет и перестаёт работать, все программы которые её используют вылетают

    вот функция

    function NewSEND (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    begin
    result := send(s, Buf, len, flags);
    end;

    Как видно тут даже не какого переопределения нет, но всё равно не работает. почему?
     
  2. Explode Sense

    Explode Sense New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2006
    Сообщения:
    130
    Адрес:
    Russia
    а send это функция по старому (оригинальному) адресу? Если иначе, то ты свою же NewSEND вызываешь)
     
  3. sin

    sin New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2008
    Сообщения:
    5
    Можно поподробнее на счёт "а send это функция по старому (оригинальному) адресу?"

    она вызавается из библиотеки winsock, я наверно приведу полный код, потомучто сижу над ним оч долго и не могу понять в чём дело:


    library iSystem;

    uses Windows, sysutils, winsock;



    type
    OldCode = packed record
    One: dword;
    two: word;
    end;


    far_jmp = packed record
    PuhsOp: byte;
    PushArg: pointer;
    RetOp: byte;
    end;

    var Ws: THANDLE;

    JmpSEND: far_jmp; //

    OldSEND: OldCode; //

    SENDADDR: pointer; //

    Bytes: dword; //




    Procedure Unhook();
    var
    Bytes: dword;
    begin
    WriteProcessMemory(INVALID_HANDLE_VALUE, SENDADDR, @OldSEND, SizeOf(OldCode), Bytes);
    end;

    function NewSEND (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    var t:TExtfile;
    Commline :string ;
    i:integer;
    begin
    result := send(s, Buf, len, flags);
    messagebox(0, '', '', 0);

    Commline := getcommandline;
    AssignFile(t, 'C:\' + inttostr(i) + '.txt'); // ну так быть не должно, это чисто для себя
    rewrite(t);
    write(t, #13#10 + Commline + ' Buf= ' + Buf);
    i := i + 1;
    closefile(t);

    end;

    Procedure SetHook(); //вот скорее всего здесь какая то ошибка, незнаю какая.
    var
    Bytes: dword;
    begin
    try
    Ws := loadLibrary('wsock32.dll');
    if (Ws <> 0 ) then
    SENDADDR := GetProcAddress(Ws, 'send');
    finally
    freeLibrary(Ws);
    end;
    ReadProcessMemory(INVALID_HANDLE_VALUE, SENDADDR, @OldSEND, SizeOf(OldCode), Bytes); //


    JmpSEND.PuhsOp := $68;
    JmpSEND.PushArg := @NewSEND;
    JmpSEND.RetOp := $C3;


    WriteProcessMemory(INVALID_HANDLE_VALUE, SENDADDR, @JmpSEND, SizeOf(far_jmp), Bytes);
    end;

    Function MessageProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
    begin
    CallNextHookEx(0, Code, wParam, lparam);
    Result := 0;
    end;

    Procedure SetGlobalHookProc();
    begin
    SetWindowsHookEx(WH_GETMESSAGE, @MessageProc, HInstance, 0);
    Sleep(INFINITE);
    end;

    Procedure SetGlobalHook();
    var
    hMutex: dword;
    TrId: dword;
    begin
    hMutex := CreateMutex(nil, false, 'SysDll');
    if GetLastError = 0 then
    CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else
    CloseHandle(hMutex);
    end;

    procedure DLLEntryPoint(dwReason: DWord);
    begin
    case dwReason of
    DLL_PROCESS_ATTACH: begin
    SetGlobalHook();
    Randomize();
    SetHook()
    end;
    DLL_PROCESS_DETACH: UnHook();
    end;
    end;


    begin
    DllProc := @DLLEntryPoint;
    DLLEntryPoint(DLL_PROCESS_ATTACH);
    end.

    Вот и всё, этот код рвёт все соединения.
    Плиз подскажите что делать, где здесь ошибка? Я уже незнаю у кого спросить.


    PS сама задача это перехват http запросов, без всякой модификации, просто поймал и сохранил.
    Может есть у кого рабочие примеры?
     
  4. Hellspawn

    Hellspawn New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2006
    Сообщения:
    310
    Адрес:
    Москва
    на вскидку, у тебя будет зацикливанее в сенде :)
    Код (Text):
    1. function NewSEND (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    2. begin
    3. result := send(s, Buf, len, flags); // вызываем уже перехваченную функцию
    4. end;
    Explode Sense правильно предположил.
     
  5. sin

    sin New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2008
    Сообщения:
    5
    Так что делать тогда?
     
  6. Explode Sense

    Explode Sense New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2006
    Сообщения:
    130
    Адрес:
    Russia
    >Так что делать тогда?
    Хммм, ты уверен, что не рано перехватами занялся? По логике, чтобы не зацикливать вызов, тебе нужно вызывать СТАРУЮ функу send. Учитывая, что ты её в винсоке пропатчил на свою (адрес в твоём модуле), send(bla-bla-bla) вызывает твою же NewSEND. Вывод? Вызывать нужно старую send, то есть перед патчем винсока тебе нужно старый (оригинальный) адрес сохранить. Это всё по сути, базис перехватов, почитай статьи Рема хотя бы, всё сразу будет понятно. Тему, имхо, нужно переместить в бегиннерс.
     
  7. sin

    sin New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2008
    Сообщения:
    5
    Да и так уже пробывал

    type
    WSEND = function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    .......

    var
    Tsend:WSEND;

    Tsend := @SENDADDR;
    result := Tsend(s, Buf, len, flags);

    .....

    Procedure SetHook();

    try
    Ws := loadLibrary('wsock32.dll');
    if (Ws <> 0 ) then
    SENDADDR := GetProcAddress(Ws, 'send');
    finally
    freeLibrary(Ws);
    end;

    ...

    end;

    вот он настоящий адреес переходит на Tsend, результат тотже.
     
  8. Hellspawn

    Hellspawn New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2006
    Сообщения:
    310
    Адрес:
    Москва
    sin учить матчасть! больше никак, у тебя таже ошибка опять :)
     
  9. sin

    sin New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2008
    Сообщения:
    5
    Уважаемые участники, вы видите мою ошибку и я её понял. Я буду бесконечно благодарен вам, поправте меня.
    Как мне следует тогда сохранить тру-адрес до боли заюзаной send ?
     
  10. Explode Sense

    Explode Sense New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2006
    Сообщения:
    130
    Адрес:
    Russia
    :) ну в том коде что ты дал как минимум Tsend := @SENDADDR; заменить на Tsend := SENDADDR; чтобы корректно сохранить адрес.

    added
    #2* блин. Comer_ прав, адреса тут не причём. Извиняюсь, ошибся.
     
  11. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    блин, ну и что, все видят и никто не может сказать? а потом комер же оказывается плохим и комера же надо банить потому что он, видите ли, флудит >.\

    действия в хукнутом сенде:
    Unhook()
    send() // <<< original ws2
    Hook()

    неплохо бы добавить критикал.
    функция твоя порождает безусловную рекурсию, что и пытались сказать профессора выше.
    для того чтобы вызвать оригинал, надо восстановить байты сплайснутой функции.
    читай про сплайсинг. на васме, я уверен, оно есть.