Trao đổi với tôi

http://www.buidao.com
Showing posts with label [TASM]. Show all posts
Showing posts with label [TASM]. Show all posts

3/14/10

[TASM] Writing a DLL in tasm32

Author: Benina
My blog: rootbiez.tk
Download : [source]
Bài viết tóm tắt cách tạo 1 dll trong tasm32. Ở đây ko nói về lý thuyết dll. Bài này chỉ là một bài thực hành. Tôi viết chỉ để lưu trữ cho riêng tôi.
Một dll cơ bản như sau:

   1:                          .586p
   2:                          .model  flat, stdcall
   3:                          locals
   4:                          jumps
   5:                          
   6:  include                 c:\tasm32\include\shitheap.inc
   7:  include                 dll.inc
   8:  include                 struct.inc
   9:   
  10:                          .data
  11:  String1              db      "kernel32.dll", 0
  12:  hmodule              dd      ?
  13:   
  14:                          .code
  15:  ;dllmain, entrypoint dll
  16:  start                   proc
  17:                          arg     imagebase
  18:                          arg     reason
  19:                          arg     reserved
  20:                          
  21:                          pushad                       
  22:                          cmp     reason, 1
  23:                          jne     __e_dllinit
  24:   
  25:               ;(code here)
  26:   
  27:  __e_dllinit:            popad
  28:                          mov     eax, 1
  29:                          leave
  30:                          retn    0ch
  31:                          endp
  32:                          
  33:  public my_Function
  34:  my_Function:
  35:                          ;code my func to export
  36:                          Retn
  37:   
  38:  end     start
  39:   
.Phân tích:

0/Header file:

   1:                          .586p
   2:                          .model  flat, stdcall
   3:                          locals
   4:                          jumps

.586p :Dùng các chỉ thị của bộ vi xử lý 586p trở lên
.model flat, stdcall : Bộ nhớ dùng flat memory model. Và quy ước gọi hàm là stdcall
jumps : Làm cho TASM tìm ra vị trí của một lệnh nhảy có điều kiện.
locals : Cho phép block-scoped symbols

1/Giá trị trả về của dllmain retn 0ch:

Phần khởi trị đầu tại entry point của chương trình của bạn phải quite với một chỉ lệnh ret 0Ch và ko exit với ExitProcess như file exe. Lý do đơn giản là loader gọi entry point gống như sau:

   1:  BOOL WINAPI DllEntryPoint(
   2:                  HINSTANCE  hinstDLL,        // handle of DLL module
   3:                  DWORD  fdwReason,           // reason for calling function
   4:                  LPVOID  lpvReserved         // reserved
   5:                 );
Nói một chút về lệnh RETN: Lệnh “RETN 4” có nghĩa là chuyển điều khiển EIP đến [esp+4] tức là sẽ bỏ qua 4 bytes addr trên stack để lấy addr cho EIP tại esp+4.
Chúng ta chú ý:
Ta có 4 tham số cho hàm proc của dll:

                        arg     imagebase
                        arg     reason
                        arg     reserved
Vì vậy theo như lệnh retn nói trên chúng ta sẽ trả về : retn 0ch
2/Tham số reason:
Có các giá trị sau:

Setting                 Value   Description
DLL_PROCESS_ATTACH      1       New process has started
DLL_THREAD_ATTACH       2       New thread has been created
DLL_THREAD_DETACH       3       Thread is about to be terminated
DLL_PROCESS_DETACH      0       Process is about to terminate

DLL đụoc gọi khi nó bị gắn vào process hay thread hay khi nó tách ra từ một process hay thread. Do đó tham số reason sẽ có các giá trị trên

3/Exported func được viết như sau:

 public myFunction
 
 myFunction PROC
     ; your code goes here ...
     ret
 myFunction ENDP

Hay

public my_Function
my_Function:
                        ;code my func to export
                        Retn

Nếu bạn ko hai báo func của bạn là publuc thì linker sẽ cho bạn cảnh báo.

4/Bảo quản thanh ghi:

Vài thanh ghi phải được bảo quản trong DLL entrypoint của chúng ta. Điều này rất quan trọng, nếu bạn ko bảo quản (preserve) chúng thì process loaded DLL sẽ kết thúc mà ko đưa ra thông báo lỗi gì sau khi DLL entrypoint đã run. Tôi ko biết những thanh ghi gì được bảo quản, nhưng ESI là chắc chắn. Một cách tốt nhất là dùng PUSHAD và POPAD để bảo quản tất cả các thanh ghi. Giá trị trả về chỉ quan trọng khi entrypoint được gọi với giá trị DLL_PROCESS_ATTACH cho tham số reason. Nó phải khác zero vì mục đích là đề xuất với hàm LoadLibrary API rằng khởi trị đầu thành công. Nó trả về zero thì DLL sẽ remove khỏi process. Vì vậy sau cùng của dll ta cần set eax:

                        mov     eax, 1
                        leave

5/Viết file .def:

Để export hàm của bạn, bạn cần write một file '.def'
Các file definition files (.def) này dường như rất giống C++. Tôi ko biết nhiều về chúng nhưng tôi biết bạn có thể viết như sau cho việc export hàm của bạn:
EXPORTS
myFunction

File .def nên đặt cùng tên với file asm của dll

6/Các file inc được kèm vào như dll.inc:

Dùng để chứa các hàm import, ví dụ

extrn ActivateActCtx:proc
extrn AddAtomA:proc
extrn AddAtomW:proc

còn struct.inc, để chứa các cấu trúc phục vụ cho coding dll

7/Biên dịch:

Không có resource, ta tạo file bat để biên dịch:

;------------------------------------------------------------------------------
@echo off
 
if exist %1.obj del %1.obj
if exist %1.exe del %1.exe
 
: -----------------------------------------
: assemble *.asm into an OBJ file
: -----------------------------------------
 
C:\tasm32\bin\TASM32.EXE  /ml /z /m9 /q  %1.asm
 
if errorlevel 1 goto errasm
 
: -----------------------
: link the main OBJ file
: -----------------------
 
c:\tasm32\bin\tlink32  /Tpd /aa /c /x  %1.obj,,,c:\tasm32\importlib\import32.lib,%1.def
 
if errorlevel 1 goto errlink
 
;----------------------------
;pewrite
;---------------------------
 
c:\tasm32\tasm32\pewrite %1.exe
 
if errorlevel 1 goto errpewrite
 
goto TheEnd
 
:errlink
 
: ----------------------------------------------------
: display message if there is an error during linking
: ----------------------------------------------------
 
echo.
echo There has been an error while linking this project.
echo.
goto TheEnd
 
:errasm
 
: -----------------------------------------------------
: display message if there is an error during assembly
: -----------------------------------------------------
 
echo.
echo There has been an error while assembling this project.
echo.
 
goto TheEnd
 
: -----------------------------------------------------
: display message if there is an error during pewrite
: -----------------------------------------------------
 
:errpewrite
 
echo.
echo There has been an error while pewrite this project.
echo.
 
goto TheEnd
 
:TheEnd
 
:if exist %1.obj del %1.obj
 
pause
 
;----------------------------------------------------------

Ví dụ cụ thể:

a/dll.asm như sau:

   1:                  .586p
   2:                          .model  flat, stdcall
   3:                          locals
   4:                          jumps
   5:                       
   6:  include                 dll.inc
   7:   
   8:                          .data
   9:   
  10:   msg_title   DB "Dll title",0
  11:   msg_message DB "Hello World! dll loader",0
  12:   msg_message_func DB "dll func loader",0
  13:   
  14:   
  15:   
  16:                          .code
  17:  ;dllmain, entrypoint dll
  18:  start                   proc
  19:                          arg     imagebase
  20:                          arg     reason
  21:                          arg     reserved
  22:                          
  23:                          pushad                       
  24:                          cmp     reason, 1
  25:                          jne     __e_dllinit
  26:   
  27:                  ;(code here)
  28:          push 0
  29:          push offset msg_title
  30:          push offset msg_message
  31:          push 0
  32:          call MessageBoxA
  33:   
  34:  __e_dllinit:            popad
  35:                          mov     eax, 1
  36:                          leave
  37:                          retn    0ch
  38:                          endp
  39:  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                        
  40:  public myFunction
  41:   
  42:  myFunction PROC
  43:          push 0
  44:          push offset msg_title
  45:          push offset msg_message_func
  46:          push 0
  47:          call MessageBoxA
  48:       ret
  49:  myFunction ENDP
  50:   
  51:  end     start

b/dll.inc như sau:

extrn ExitProcess:proc
extrn MessageBoxA:proc

c/dll.def như sau:

EXPORTS
myFunction

d/Loader gọi hàm trong dll như sau:

Phần loader này ko kiểm tra giá trị trả về của các APIs:

   1:                          .586p
   2:                          .model  flat
   3:                          locals
   4:                          jumps
   5:                          
   6:  extrn ExitProcess:proc
   7:  extrn MessageBoxA:proc
   8:  extrn LoadLibraryA:proc
   9:  extrn GetProcAddress:proc
  10:   
  11:   
  12:  o    equ     offset
  13:   
  14:  .data
  15:   
  16:      msg_title   DB "MessageBox title",0
  17:      msg_message DB "Hello World!",0
  18:   
  19:      dllname db "dll.DLL",0
  20:      dllfunc db "myFunction",0
  21:   
  22:      hlib dd ?
  23:      fn_myFunction dd ?
  24:   
  25:  .code
  26:  start:                 
  27:   
  28:          push 0
  29:          push offset msg_title
  30:          push offset msg_message
  31:          push 0
  32:          call MessageBoxA
  33:   
  34:          push o dllname
  35:          call LoadLibraryA
  36:          mov hlib,eax
  37:   
  38:   
  39:          push o dllfunc
  40:          push hlib
  41:          call GetProcAddress
  42:          mov fn_myFunction,eax
  43:   
  44:          call fn_myFunction
  45:   
  46:          push 0
  47:          call ExitProcess
  48:   
  49:   end     start

1/22/10

[TASM] MicroSoft Windows Sockets Guide

by Bumblebee/29a

Tranz by Benina

Index

~~~~~

1.Overview (tổng quan)

2.What is windows sockets? (windows sockets là gì?)

3.Micro$oft extensions (các hàm mở rộng của M$)

4.Step by step: make a connection (hường dẫn từng bước tạo một kết nối)

5.Read and Write (đọc và viết)

Apendix: wsocks.inc (thư mục đính kèm)

1.Overview

~~~~~~~~~~

Đây ko phải là một bài hướng dẫn đặc biệt gì cả . Chỉ là những ghi chép lại việc tôi tìm hiểu qua quá trịnh thực hiện win32 sockets of chuẩn BSD socket standards. Bài này có thể giúp bạn làm một remote connection (liên kết từ xa) với virus của bạn vì dụ như để send một e-mail chẳng hạn.

Nói đơn giản là mô tả một đọan code từ i-worm.Anaphylaxis.

2.What is windows sockets?

~~~~~~~~~~~~~~~~~~~~~~~~~~

Đặc điểm của Windows Sockets là định nghĩa một giao diện lập trình mạng network programming cho Microsoft Windows, mà nó được đặt nền tảng trên mô hình "socket" đã được phổ biến tại Berkeley Software Distribution (BSD). Nó bao gồm cả hai lọai “Berkeley socket style routines” (các thủ tục theo kiểu mẫu socket của Berkeley) và cài đặt các phần mở rộng đặc trưng của Windows (Windows-specific extensions) rất quen thuộc đã được thíết kế cho phép lập trình viên có được tiện lợi điều khiển thông điệp một cách tự nhiên trong Windows.

Nhưng, socket là cái quái gì vậy? Ý tưởng của BSD là một file để điều khiển từ xa máy tính (machine). Sokects đươc sử dụng trong BDS giống như các files đơn giản. Bạn có thể sử dụng thông thường như 'write' và 'read' để viết và đọc từ socket. Nhưng M$ thay đổi sự trừu tượng của level (lớp) này và cho bạn các hàm đặc biệt để làm cho bạn nhớ rằng bạn đang sử dụng các hàm API chết tiệt của họ.

3.Micro$oft extensions

~~~~~~~~~~~~~~~~~~~~~~

Da6y là các hàm functions được cung cấp bởi M$ mà chúng ko có trong

Berkeley:

         WSAAsyncGetHostByAddr()
WSAAsyncGetHostByName()
WSAAsyncGetProtoByName()
WSAAsyncGetProtoByNumber()
WSAAsyncGetServByName()
WSAAsyncGetServByPort()
WSAAsyncSelect()
WSACancelAsyncRequest()
WSACancelBlockingCall()
*WSACleanup()
WSAGetLastError()
WSAIsBlocking()
WSASetBlockingHook()
WSASetLastError()
*WSAStartup()
WSAUnhookBlockingHook()

M$ cung cấp các hàm quỷ quái này bởi vì cách hoạt động của Windows là thực hiện đa tác vụ (multitasking). Chuyện gì xảy ra nếu một ứng dụng chờ một sự kết nối(connection)? Kết nối (connection) yêu cầu ứng dụng phải “xem xét” nó một cách bắt buộc nếu kết nối là ok. Vì vậy ứng dụng ko thể lấy các thông điệp windows đang gởi đến chúng. Các hàm chỉ ra phía trên cung cấp các công việc không bị ngăn chặn (nonblocking work) như cơ chế nói trên.

Chúng ta chỉ quan tâm đến các hàm đánh dấu sao '*'. Những hàm khác ko cần thiết vì tôi sẽ sử dụng socks theo cách thức BSD (BSD=UNIX=LUNUX rulez!).

4.Step by step: make a connection

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Bước đầu tiên chúng ta làm là kiểm tra sự cài đặt wsocks trong máy tính. Chúng ta sẽ sử dụng wsocks 1.1, vì vậy chúng ta tạo ra một check (kiểm tra) với hàm WSAStartup.

        push    offset wsadata                  ; WSADATA struct
push VERSION1_1 ; we want version 1.1
call WSAStartup ; check wsocks installation
cmp eax,0 ; on error:
jne qApp ; exit app

mov ax,VERSION1_1 ; WSAStartup returns the version
cmp ax,word ptr [wsadata.mVersion] ; test version
jne exitAppQsocks ; quit sockets and exit App

Hàm WSAStartup cần 2 đối số: một con trỏ pointer đến cấu trúc WSADATA struct và số version yêu cầu cần thiết để ứng dụng hoạt động. Hàm API này trả về (retuns) trong thành phần .mVersion của cấu trúc WSADATA số version thấp nhất có thể sử dụng mà bạn cần biết hay sẽ báo lỗi xảy ra nếu hàm thất bại. Hơn nữa hàm WSAStartup sẽ báo cho Windows biết bạn đang sử dụng wsocks. Vì vậy khi version mà bạn yêu cầu ko phù hợp thì bạn cần thiết phải gọi hàm WSACleanup để xóa bỏ trạng thái của Windows bị gây ra trước đó do gọi hàm WSAStarup:

        call    WSACleanup                ; end wsocks use

Giả sử bây giờ chúng ta có version mà chúng ta cần. Tại điềm này chúng ta cần open một socket.

        push    PCL_NONE            ; protocol
push SOCK_STREAM ; type of socket
push AF_INET ; family
call socket ; open a socket
cmp eax,SOCKET_ERR ; on error:
je doCleanUp ; WSACleanup

Hàm socket cần 3 tham số: protocol, type và family.

Tham số protocol có thể được set nhưng điều này có thể làm cho cơ chế bảo mật của windows hủy bỏ kết nối (connection) của chúng ta. Ví dụ: chúng ta muốn tạo ra một telnet connection. Nếu chúng ta set protocol thành telnet protocol và Windows thì ko cho phép sử dụng protocol này thì socket của chúng ta sẽ bị sai (fails). Vì vậy cách tốt nhất là set protocol là none.

Tham số type of socket có thể là: STREAM hay DATAGRAM. Đầu tiên là định hướng đến kết nối (connection) và thứ hai là gởi các packets mà chúng có thể đến nơi nhận (receiver) theo thứ tự khác nhau khi chúng đã được gởi đi. Hơn nữa người gởi (sender) sẽ ko thể biết được packet có đến nơi nhận hay ko khi ko cần sự trợ giúp phản hồi của người nhận (receiver).

Tham số sau cùng family có thể là: AI_UNIX, AF_INET... nhưng chỉ các AF_INET addresses được hổ trợ trong version mà tôi kiểm tra.

Chúng ta sử dụng PCL_NONE, SOCK_STREAM và AF_INET. Hàm socket trả về (returns) giá trị SOCKET_ERR (-1) nếu hàm gọi bị sai và trả về socket handle nếu hàm gọi thành công.

Bước cuối cùng là tạo ra một kết nối (connection). Theo lý thuyết chúng ta connect (kết nối) socket, điều đó được dùng để quản lý kết nối (connection), là điều khiển từ xa máy tính. Trước tiên chúng ta cần lắp giá trị vào cấu trúc SOCKADDR struct (đây là cấu trúc đã bị chỉnh sửa (modified struct): tôi đã kết hợp các cấu trúc khác lại vì vậy chúng ta sẽ chỉ sử dụng cho loại AF_INET).

    SOCKADDR        struct
sin_family dw 0 ; ever AF_INET
sin_port dw 0 ; the port
sin_addr dd 0 ; addr of server node
sin_zero db 8 dup(0) ; not used
SOCKADDR ends

sin_family thì dễ dàng được lắp trị vào, nhưng sin_port và sin_addr thì phức tạp hơn. sin_port là port (cổng) mà ở đó chúng ta muốn connect(kết nối). Nhưng số này phải là số byte thứ tự của network (network byte order)(nguyên cứu thêm về mô hình mạng). Sockets cung cấp hàm htons để làm điều này:

        push    PORT                    ; number of port
call htons ; get port in network byte
mov word ptr [sockaddr.sin_port],ax ; order

Hàm htons lấy port và trả về returns một WORD chứa network byte order.

sin_addr thì phức tạp nhất. Chúng ta cần addr of host đề connect (kết nối). Đây là một số number dùng để nhận dạng ra nút (node) trên mạng (mạng là sự truyền thông giữa các node). Nhưng thông thường chúng ta lại có định dạng như sau 'domain.ext' (ví dụ: IBM.com, netscape.com,...). Vì vậy chúng ta phải lấy IP của nó (xxx.xxx.xxx....) mà chúng có định dạng dotted format và rồi lấy địa chỉ của nó.

        push    offset server            ; addr of the string ('oeee.net')
call gethostbyname ; get the hostent struct
cmp eax,0 ; on error:
je exitQsocksC ; close sock, cleanup and exit app
; eax contains the pointer to HOSTENT

mov eax,dword ptr [eax+HOSTENT_IP] ; get pointer to IP into HOSTENT
mov eax,dword ptr [eax] ; get pointer to IP
mov dword ptr [sockaddr.sin_addr],eax ; that's all!

push sizeOfSockaddr ; the size of sockaddr struct
push offset sockaddr ; the addr of sockaddr
push dword ptr [fd] ; the handle of the socket
call connect ; connect now!
cmp ax,SOCKET_ERR ; on error:
je exitQsocksC ; close sock, cleanup and exit app

Ví dụ này tương đối đầy đủ rõ ràng: chúng ta lấy trong cấu trúc HOSTENT mà nó có thành phần HOSTENT_IP là addr IP of nút (node) trên mạng. Rồi lắp giá trị vào sin_addr và cấu trúc sockaddr struct bây giờ đã sẳn sàng cho việc tạo ra kết nối (connection). Hàm connect cần các tham số sau: size of SOCKADDR struct (là hằng số vì do tôi đã chỉnh sửa cấu trúc mô tả trước đó ;), pointer đến SOCKADDR struct và handle of socket.

That's all. Chúng ta chỉ cần close socket khi công việc hoàn thành ta sử dụng hàm closesocket:

        push    dword ptr [fd]            ; handle of the socket
call closesocket

5.Read and Write

~~~~~~~~~~~~~~~~

Miscro$oft cung cấp các hàm APIs khác để đọc và viết nhưng chúng ta sẽ sử dụng hàm: send và recv.

        push    0                    ; normal (can be OOBD too)
push ecx ; size of message to send
push esi ; addr to message
push eax ; socket handle
call send

push 0 ; normal
push 4 ; size to read
push offset response ; addr to store message
push eax ; soket handle
call recv

Hàm send làm việc và cho ra các errors (lỗi) tương tự như hàm _lwrite và cũng xảy ra tương tự với hàm recv và hàm _lread tương ứng.

Hàm send và recv đang bị block (ngăn chặn). Điều này có nghĩa là nếu bạn đang sending hay receiving và không có dữ liệu nào được send/receive, thì socket sẽ ngăn chặn ứng dụng cho đến khi có data sẳn dàng để dùng, kết nối (connection) bị sai fails hay process kết thúc. Vì vậy đây là điều cuối cùng những gì chúng ta cần sử dụng. Chúng ta cài đặt một thread và thead này tạo ra một kết nối (connection) và sends/receives (gởi/nhận) các thông điệp messages (tạo ra sự truyền thông). Main process (tiến trình chính) mà chúng cài đặt ra thread chỉ để chờ time (thời gian) cho phép thread làm việc. Nhưng nếu thread bị blocked time (thời gian) trong main process mất hiệu lực . Thì main process kết thúc thread và tiếp tục công việc của nó.

That's all folks!

 APENDIX: wsocks.inc

;
; WSocks.inc: include file for windows sockets .
; Designed for TASM5 and Win32.
;
; (C) 1999 Bumblebee.
;
; This file contains basic structures and stuff to work
; with windows sockets.
;

; Descriptions of the API:
; arguments in order of PUSH ;)

; only for debug
extrn WSAGetLastError:PROC

; starts the use of winsock dll
; addr WSADATA, version requested
; returns: 0 ok
extrn WSAStartup:PROC

; terminates the use of winsock dll
; returns: SOCK_ERR on error
extrn WSACleanup:PROC

; opens a new socket
; protocol (PCL_NONE), type (SOCK_??), addr format (AF_??)
; returns: socket id or SOCKET_ERR (socket is dw)
extrn socket:PROC

; closes a socket
; socket descriptor
;
extrn closesocket:PROC

; sends data (this socks are a shit... Unix uses simple write)
; flags (1 OOB data or 0 normal ) , length, addr of buffer, socket
; returns: caracters sent or SOCKET_ERR on error
extrn send:PROC

; reveives data (this socks are a shit... Unix uses simple read)
; flags (use 0), length, addr of buffer, socket
; returns: caracters sent or SOCKET_ERR on error
extrn recv:PROC

; connects to a server
; sizeof struct SOCKADDR, struct SOCKADDR, socket
; returns: SOCKET_ERR on error
extrn connect:PROC

; gets the name of the current host
; length of the buffer for name, addr of buffer for name
; return: SOCKET_ERR on error
extrn gethostname:PROC

; gets strcut hostent
; addr of name
; returns: ponter to the struct or 0 on error
extrn gethostbyname:PROC

; converts a zstring like "xxx.xxx.xx...." to netw byte order
; zstring ptr to change to dotted addr format
; returns: in_addr (dd)
extrn inet_addr:PROC

; dw to convert into netw byte order (usually the port)
; returns: the value in network byte order (dw)
extrn htons:PROC

; Structs :o

; sockaddr struct for connection
; modified (for better use)
; if you want the original look for it into a winsock.h
SOCKADDR struct
sin_family dw 0 ; ex. AF_INET
sin_port dw 0 ; use htons for this
sin_addr dd 0 ; here goes server node (from inet_addr)
sin_zero db 8 dup(0)
SOCKADDR ends

; for WSAStartup diagnose
WSADATA struct
mVersion dw 0
mHighVersion dw 0
szDescription db 257 dup(0)
szSystemStatus db 129 dup(0)
iMaxSockets dw 0
iMaxUpdDg dw 0
lpVendorInfo dd 0
WSADATA ends

; Some nice equs

; what version of winsock do you need? (usually 1.1)
VERSION1_0 equ 0100h
VERSION1_1 equ 0101h
VERSION2_0 equ 0200h

AF_UNIX equ 1 ; local host
AF_INET equ 2 ; internet (most used)
AF_IMPLINK equ 3 ; arpanet
AF_NETBIOS equ 17 ; NetBios style addresses

; types of sockets
SOCK_STREAM equ 1 ; stream (connection oriented; telnet like)
SOCK_DGRAM equ 2 ; datagram (packets, packets, packets)

; protocol
PCL_NONE equ 0 ; none (define the protocol not needed)

SOCKET_ERR equ -1 ; standard winsock error

HOSTENT_IP equ 10h ; where is the IP into the hostent struct


APENDIX ENDS

11/30/09

[TASM] TASM32+HiEditor+ResEd

Gói Editor này cho TASM đã lâu rồi. Khi nào rãnh tôi sẽ post gói mới tôi đang sử dụng.

By:benina

I had configed a tasm32 for newbies studying coding tasm with deroko.

+This RAR include:
-TASM32 ver 5.3+5.0
-ResEd 1.1.4.3
-HiEditor V2.0.1.3
-INC files of deroko ARTeam


+Using:
-Unrar to fodler c:\tasm32
-Edit and Build ALL on memu.

+Link
http://benina.rea.googlepages.com/tasm32.part01.rar
http://benina.rea.googlepages.com/tasm32.part02.rar
http://benina.rea.googlepages.com/tasm32.part03.rar
http://benina.rea.googlepages.com/tasm32.part04.rar
http://benina.rea.googlepages.com/tasm32.part05.rar
http://benina.rea.googlepages.com/tasm32.part06.rar
http://benina.rea.googlepages.com/tasm32.part07.rar
http://benina.rea.googlepages.com/tasm32.part08.rar
http://benina.rea.googlepages.com/tasm32.part09.rar