Когда-то давно я создавал тред в котором просил помощи в написании кода для чтения буфера. Как потом выяснилось, игра использовала RSA шифрование из-за которого я не смогу понять какие данные там передаются. Я забил на эту игру. Совсем недавно мне понадобился этот код для вывода байт буфера в консоль. Тогда я тестировал его на WSASend и он работал, но сейчас мне нужно вывести содержимое буфера WSARecv. И по идее это должно работать, но почему-то выводятся нолики. А при обычном cout << lpBuffers->buf << endl выводит просто нихуя. Помогите понять в чем проблема. Игра использует функции WSARecv и recv. Я пробовал перехватывать функцию recv и делать сразу return 0 но игра по прежнему работала, по этому я думаю что главная функция принятия данных это WSARecv. Скриншот API вызовов этих функций и их подробности прилагаю.
>>239336613 В for изменил lpBuffers на buffer но все так же нули.
>>239336665 Мне нужно данные буфера получить и решить допускать ли их до клиента или нет. Данные уже приняты и находятся в буфере, но почему-то я не могу их вывести.
>>239337173 >А с WSASend так же? WSASend отправляет данные. Т.е. в приложении уже есть какой-то буффер с данными которые ты хочешь отправить. Поэтому он не пустой.
А WSARecv получает данные, поэтому буффер изначально пустой
>>239337322 Да будет. Но еще зависит от того как приложение обрабатываешь такие ошибки. Может оно вообще не ожидает что такое может случится и вылетит с крэшем
>>239336613 тебя не смущает что ты должен вызвать _WSARecv, который запишет ответ в lpBuffers и сохранив ретурнавалюа, а потом выводить lpBuffers? или ты ебанутый и целевой буффер до заполнения хочешь смотреть?
>>239339307 Там вроде в readfds можно что-то указать, или например как-то из WSARecv высчитать сколько данных получил и выдрать как-то из самого сокета при вызове select (хз можно ли так вообще)
>>239339261 Ну представь себе что ты писал это приложение. Ты выделяешь буффер под пакет из сети, вызваешь функцию чтения из сокета, а на выходе нихуя. Ну ты такой ладно, дисконнектим, завершаем всю хуйню
>>239339644 >2. ты можешь вызывать не _WSARecv(...lpBuffers) а подготовить свой tmplpBuffers (подготовить память по размерам исходного lpBuffers и в конце еще освобождать будеьш) и подставлять его в _WSARecv и если данные пропускаешь - копировать tmplpBuffers в lpBuffers
>>239339901 он и будет вызывать его просто не с оригинальным указателем куда запишется ответ, а со своим временным, обработает его и решит - нужно скопировать в целевой или нет
>>239340003 просто ты создаешь временный контейнер который подставишь вместо lpBuffers
>>239341029 нет, это ошибочный код - ты на си с памятью умеешь работать или просто макака?
>>239341409 в этом коде ничего не изменилось тк ты просто взял указатель и сохранил в другую переменную - в итоге результат запишется в тоже место что и раньше
>>239341294 изучай приходящие dwBufferCount, lpBuffers - это массив WSABUF я так поянл игра готовит под них память и подставляет в эту функцию - нужно сздать такую же
поэтмоу тебе и нужно изучить что на вход подает игра\приложение и дальше решать что будет если там всегда dwBuffercount = 1 то можешь обойтись WSABUF buf; DWORD cnt = 1; buf.len = origbuf->len; buf.buf = new char[buf.len]; // не забудь потом delete buf.buf _WSARecv(...., &buf, &cnt,...)
>>239341957 если ты заполняешь нулями - это все равно результат просто с нулями, прилжение прочитает и поймет что ты хуйню прислал - я тебе говорил что возможно нужно давать int ответ что ошибка какая-либо по кодам ошибок wsarecv ты блять определись как ты хочешь отвечать приложению чтобы не дать ему данные
>>239342065 ага для этого ему придется пройтись циклом по массиву из структур WSABUF, подготовить для каждой копию внутреннего buf размером len ну или собрать сумму + с учетом размера поля len и зааллокетить байт буфер который потом кастануть к WSABUF*, но оп даже не знает как работать с памятью в си
>>239342383 ну если всегда один то вернись к >>239342188 test.buf = new byte[lpBuffers->len]; test.len = lpBuffers->len; тогда они будут смотреть на разную область памяти и ты не затронешь оригинал который пришел в функцию если захочешь чтобы результат применился сделаешь memcpy из test.buf в lpBuffers->buf в конце не забудь delete test.buf;
>>239342383 но опять таки я тебе напоминаю что это махинации с данными и ты соснешь хуй тк приложение ждет свои данные - дать ему нулевой результат - быть посланым нахуй чтобы отказать ей в получении может нужно делать int res = _WSARecv(...); if(оп решил что не давать данные) return WSAETIMEDOUT else return res;
>>239342814 в том что ты ставил *lpBuffers = 0 это фактически записать в память по адресу число 0, т.е. там лежит WSABuf и твоя запись запишет в WSABuf::len поле 0, массив при этом останется с данными, ну ты его тоже можешь нулями заполнить но приложение примет это все равно за данные с нулями внутри где в пакете сказали что вроде длина 0 но как обработается - на усмотрение приложения, это не ошибка и не отказ от выдачи ответа
>>239343084 Сервер шлет данные. Данные не зашифрованы и мне нужно иметь возможность не допускать до клиента неугодные мне данные таким образом чтобы не выкинуло с сервера / крашнуло. Как будто их не было.
>>239343193 ты должен знать как реагирует сервер на ответ ты не можешь не допустить просто так чтобы не выкинуло он делает запрос - под запрос получает ответ ты не можешь в ответе написать хуй и чтобы он это принял за валидный ответ
>>239343193 А ты знаешь, что за данные в пакетах? Просто может быть такое, что просто из-за того, что пакет не придет с какой-то инфой, то клиент решит, что соединение потеряно. Но ты вроде на верном пути. Хук норм тема. Попробуй менять данные и отправлять после хука в клиент какую-то нибудь поебень. Ну то есть данные ты не можешь отправить. Если дашь ошибку, то клиент попробует сделать реконнект. Попробуй найти пакет, который не несёт какого-либо смысла, но сервер его отправляет. Очень большой вопрос, что отправить нужно, чтобы не было реконнекта и прогу не крашнуло.