По просьбе некоторых участников форума написал на ассемблере несколько процедур для работы с сервисом anti-captcha.com, спроектировал процедуры так, чтобы они могли в несколько потоков одновременно работать. Для теста написал программу, которая может распознавать капчи в несколько потоков: Скачать исходники + exe Подробное описание кода
мне кажется, лучше бы было сделать dll, в экспорт вывести пару функций и приложить подробное описание, чтобы можно было бы заюзать в любом софте. было бы полезнее
Собрал dll и дополнительную версию проги для тестирования, которая работает с этой dll. Немного оптимизировал функции по размеру, dll получилась всего 4кб. Описание функций, экспортируемых dll: AntiCaptchaInit - вызывается для инициализации работы с антикапчей, ей не надо передавать параметры, вернет 0 в случае успеха. AntiCaptcha - вызывается для отправки изображения на сервер. Вернет 0 в случае успеха или код ошибки. Параметры: Code: AntiCaptcha PROC, [указатель на память, куда записывать ID капчи - буфер не менее 30 байт, туда будет записана строка], [указатель на строку с ключом антикапчи], [1 или 0 - состоит ли капча из нескольких слов], [1 или 0 - регистрозависима ли капча], [1 или 0 - состоит ли капча только из цифр], [минимальная длина капчи], [максимальная длина капчи], [указатель на строку с расширением, например, "jpg"], [указатель на строку с типом, например "image/jpeg"], [размер картинки в байтах], [указатель на память, где загружена картинка] Все параметры - DWORD. AntiCaptchaAnswer - вызывается для получения распознанного варианта или статуса распознавания. Вернет 0 в случае успеха или код ошибки. Параметры: Code: AntiCaptchaAnswer PROC, [указатель на память, куда записать ответ], [указатель на память с ID капчи, полученный с помощью предыдущей функции], [указатель на строку с ключом антикапчи] Все параметры - DWORD. Коды возвращаемых функциями ошибок: Code: 1 - ошибка при создании сокета 2 - ошибка при подключении 4 - ошибка при создании запроса 5 - ошибка при отправке данных 6 - ошибка при получении данных 7 - слишком большой ответ сервера 10 - капча пока не распознана 11 - неверный ключ 12 - все работники пока заняты 13 - нулевой баланс на аккаунте 14 - несуществующий ID капчи 20 - неопределенная ошибка Еще две функции - SocketInit и SocketCleanup (им не надо передавать параметры) - это простые переходники для функций Win32api WSAStartup и WSACleanup, на всякий случай. Скачать можно по той же ссылке в первом посте.
Есть ресурс такой, anti-captcha.com, достаточно известный, для распознавания капч. У них есть свое api, и я написал несколько процедур для работы с ним. Программа - просто для теста их работы, зато прилагается еще dll, которая может работать с любым языком. Для чего нужно распознавать капчи - догадайся сам-) Вообще, код с описанием в образовательных целях хорошо пойдет - там мьютексы, потоки, сокеты...
перечитал стаью в поисках ошибок... вроде ничего кроме непонятного мне цикла с virtualAlloc в самом начале. дааа d_x ты маньяк!!! у меня конечно тоже есть программы в ~1000 строк кода на winAPI (помню делал собственную прорисовку всего интерфейса - скин, кнопочки цвет меняют все в общем крута exe ) но чтобы такое да на асме вай верх ппц теперь научись делать UNICODE версии прог, потомучто все операции со строкам выше win9X ядро венды производит в UNICODE,а функции с дополнением *A (MessageBoxA...) затрачивают время на выделение памяти и конвертирование строк в UNICODE я вот думаю если извращатся то уж по полной ! не юзать invoke, констант, описывать все нужные экспортируемые функции и тд изучаю fasm хех разницы между размером exe миимальной winAPI проги в masm32 и VS2008 я не заметил (ну конечно надо с бубном танцевать там долго чтобы получить результат)... дело вкуса!
2 d_x : я тебя сделаю! я накатал ща на masm-е пакетный сниффер в 3,5 кило хехе (правда функциональности в нем пока ноль, но уже уммет скидывать дамп входящего - исходнящего траффика на диск) вопрос в асме есть указатели? или придется вот таким тупым макаром структуры разбирать mov eax,offset buf mov eax,[eax+2] ??? а то я как бе не знаю ) хех
Ну я как бы ни с кем не соревнуюсь, я просто ради интереса и практики софт писал, недавно изучив асм. Что ты здесь подразумеваешь под указателями? Они там конечно есть, они постоянно используются, offset buf - это указатель. Насчет структур - можно так (привожу кусок своего кода): Code: .data? AC_SocketAddress sockaddr_in <> ;... .code MOV AC_SocketAddress.sin_addr,EAX invoke htons,80 mov AC_SocketAddress.sin_port,AX MOV AC_SocketAddress.sin_family,AF_INET
ну я имею ввиду нечто вроде Code: typedef struct gg { unsigned long a; unsigned long b; unsigned char c[16]; } gg; gg *ukaz; ukaz=(gg *)(buffer); printf("%d",ukaz->a); чтобы как бы удобненько пользоватся. для снифака это особено актуально структуры пакетов, заголовки и тд такое можно реализовать на асме?
ну это я тоже знаю, что можно делать структуры данных и туда значения заносить. но допустим буффер - 50000 байт заголовок пакета 44 unsigned char buffer[50000]; // 50000 выделеные в памяти (.data? buffer db 50000 dup(?)) str_paket *paket; // указатель на структуру пакета paket=(str_paket *)&buffer[0]; // теперь указатель ссылкается на смещение buffer в памяти (offset buffer) и мы можем крута и удобно юзать структуру ниче не перемещая не копируя и не заполняя pkaet->zagolovok будет эквивалентно по offset buffer + 4 pkaet->zagolovok2 offset buffer + 8 там и тд .... эм вопрос все тот же
Я, видимо, не настолько хорошо знаю си, чтобы найти какое-либо существенное отличие этого кода от того, что я написал. Да и зачем структуре в 44 байта буфер в 50000?
лан закроем тему нашу пока нашел вот нечно подобное что я хочу получить но вот как заставить ссылатся структуру другой адрес пока не придумал ) а тут тупо копирование ( похоже... простым языком я хочу "наложить" свою структуру на уже имеющиеся данные ... эх бум искать, уже хоть что-то
Как вариант придумал такое (не очень удобно, но копирования не производится и в масме работает): Code: s STRUCT ;описание структуры aaaa WORD ? bbbb WORD ? cccc BYTE ? dddd DWORD ? eeee BYTE 8 dup(?) s ENDS .data ;имеющиеся у нас данные buf db "aa" db "bb" db "c" db "dddd" db "eeeeeeee" data ? temp db 10 dup(?) .code start: mov edi,offset buf add edi,offset s.eeee ;получили доступ к последнему полю без какого-либо копирования данных ;это указывает на байты "eeeeeeee". ;или mov edi,offset buf+offset s.bbbb ;если где-то нужно использовать структуру из памяти целиком, то можно написать просто offset buf... Наверняка можно как-то более красиво написать)
Доо, это прям анреальная задача. xD Все что тебе нужно знать - это как работают перфикс rep и команды loads[b,d,w]/stos[b,d,w] или аналогичные movs[b,d,w].
2 SmanxX1 это конечно все хорошо, но одна закавыка - данные копируются... мне правда очень понравилась функция SCAS - полезная 2 d_x пока ниче круче констант equ не придумал... например psp_INT32 equ 0 psp_MemSize equ 2 psp_Reserved equ 4 потом lea esi,buffer mov eax,[esi+psp_MemSize] тоесть описывать смещения в структуре... наглядно выходит, но не очень удобно всеравно все сводится к работе с регистрами а туда больше 4 байт запихнуть не получится... а так хоть наглядно а в твоем примере драгоценные байты и такты тратятся на add хм а можно интересно offset buff + offset s.eee оказывается можно!!! mov edi,offset buf + offset s.eee работает!! )
И что? Ты представляешь себе альтернативный способ, хотябы в теории? Память все же не абстрактное пространство, в любом случаее, если что-то куда-то "перенести", то на прежднем месте что-нибудь останится, пусть даже те же нули. А как же 8ми битные регистры в 64ех разрядной архитектуре? (rax,rbx,rcx,rdx и т.д.). Пора бы их задействовать, т.к. процессоры с 32ух разрядной архитектурой уже как бэ давно не выпускаются. (ну и что, что полно юзеров с древними компами, нужно двигать прогресс и неи**т D)
Ну и зачем это? Автор добивался наоборот, что бы каждый заюзать мог. Да и написанное под 32 будет нормально пахать и под 64. PS: ТС ты мазахист Большое спс за ддлку