💾 Archived View for clemat.is › saccophore › library › ezines › textfiles › ezines › APJ › apj_1.txt captured on 2022-01-08 at 14:57:25.
⬅️ Previous capture (2021-12-03)
-=-=-=-=-=-=-
::/ \::::::. :/___\:::::::. /| \::::::::. :| _/\:::::::::. :| _|\ \::::::::::. Oct/Nov 98 :::\_____\::::::::::. Issue 1 ::::::::::::::::::::::......................................................... A S S E M B L Y P R O G R A M M I N G J O U R N A L http://asmjournal.freeservers.com asmjournal@mailcity.com T A B L E O F C O N T E N T S ---------------------------------------------------------------------- Introduction...................................................mammon_ "VGA Programming in Mode 13h".............................Lord Lucifer "SMC Techniques: The Basics"...................................mammon_ "Going Ring0 in Windows 9x".....................................Halvar Column: Win32 Assembly Programming "The Basics"..............................................Iczelion "MessageBox"..............................................Iczelion Column: The C standard library in Assembly "_itoa, _ltoa and _ultoa"...................................Xbios2 Column: The Unix World "x86 ASM Programming for Linux"............................mammon_ Column: Issue Solution "11-byte Solution"..........................................Xbios2 ---------------------------------------------------------------------- +++++++++++++++++++++++Issue Challenge++++++++++++++++++++ Write a program that displays its command line in 11 bytes ---------------------------------------------------------------------- ::/ \::::::. :/___\:::::::. /| \::::::::. :| _/\:::::::::. :| _|\ \::::::::::. :::\_____\:::::::::::..............................................INTRODUCTION by mammon_ Welcome to the first issue of Assembly Programming Journal. Assembly language has become of renewed interest to a lot of programmers, in what must be a backlash to the surge of poor-quality RAD-developed programs (from Delphi, VB, etc) released as free/shareware over the past few years. Assembly language code is tight, fast, and often well-coded -- you tend to find fewer inexperienced coders writing in assembly language than you do writing in, say, Visual Basic. The selection of articles is somewhat eclectic and should demonstrate the focus of this magazine: i.e., it targets the assembly-language programming community, not any particular type of coding such as Win32, virus, or demo programmimg. As the magazine is newly born and much of its purpose may seem unclear, I will devote the rest of this column to the most common questions I have received via email regarding the mag. How often will an issue be released? ------------------------------------ Barring hazard, an issue will be released every other month. What types of articles will be accepted? ---------------------------------------- Anything to do with assembly language. Obviously repeats of previously presented material are not necessary unless they enhance or clarify the earlier material. The focus will be on Intel x86 instruction sets; however coding for other processors is acceptable (though out of courtesy it would be good point to an x86 emulator for the processor you write on). Personally I am looking for articles on the areas of asembly language that interest me: code optimization, demo/graphics programming, virus coding, unix and other-OS asm coding, and OS-internals. Demos (with source) and quality ASCII art (for issue covers, column logos, etc) are especially welcome. For what level of coding experience is the mag intended? -------------------------------------------------------- The magazine is intended to appeal to asm coders of all levels. Each issue will contain mostly beginner and intermediate level code/techniques, as these will by nature be of the greatest demand; however one of the goals of APJ is to include enough advanced material to make the magazine appeal to "pros" as well. How will the mag be distributed? -------------------------------- Assembly Programming Journal has its own web page at http://asmjournal.freeservers.com which will contain the current issue and an archive of previous issues. The page also contains a guestbook and a disucssion board for article writers and readers. An email subscription may be obtained by sending an email to asmjournal@mailcity.com with the subject "SUBSCRIBE"; starting with the next issue, Assembly Programming Journal will be emailed to the address you sent the mail from. Wrap-up ------- That's the bulk of the "faq". Enjoy the mag! ::/ \::::::. :/___\:::::::. /| \::::::::. :| _/\:::::::::. :| _|\ \::::::::::. :::\_____\:::::::::::...........................................FEATURE.ARTICLE VGA Programming in Mode 13h by Lord Lucifer This article will describe how to program VGA graphics Mode 13h using assembly language. Mode 13h is the 320x200x256 graphics mode, and is fast and very convenient from a programmer's perspective. The video buffer begins at address A000:0000 and ends at address A000:F9FF. This means the buffer is 64000 bytes long and that each pixel in mode 13h is represented by one byte. It is easy to set up mode 13h and the video buffer in assembly language: mov ax,0013h ; Int 10 - Video BIOS Services int 10h ; ah = 00 - Set Video Mode ; al = 13 - Mode 13h (320x200x256) mov ax,0A000h ; point segment register es to A000h mov es,ax ; we can now access the video buffer as ; offsets from register es At the end of your program, you will probably want to restore the text mode. Here's how: mov ax,0003h ; Int 10 - Video BIOS Services int 10h ; ah = 00 - Set Video Mode ; al = 03 - Mode 03h (80x25x16 text) Accessing a specific pixel int the buffer is also very easy: ; bx = x coordinate ; ax = y coordinate mul 320 ; multiply y coord by 320 to get row add ax,bx ; add this with the x coord to get offset mov cx,es:[ax] ; now pixel x,y can be accessed as es:[ax] Hmm... That was easy, but that multiplication is slow and we should get rid of it. That's easy to do too, simply by using bit shifting instead of multiplica- tion. Shifting a number to the left is the same as multiplying by 2. We want to multiply by 320, which is not a multiple of 2, but 320 = 256 + 64, and 256 and 64 are both even multiples of 2. So a faster way to access a pixel is: ; bx = x coordinate ; ax = y coordinate mov cx,bx ; copy bx to cx, to save it temporatily shl cx,8 ; shift left by 8, which is the same as ; multiplying by 2^8 = 256 shl bx,6 ; now shift left by 6, which is the same as ; multiplying by 2^6 = 64 add bx,cx ; now add those two together, whis is ; effectively multiplying by 320 add ax,bx ; finally add the x coord to this value mov cx,es:[ax] ; now pixel x,y can be accessed as es:[ax] Well, the code is a little bit longer and looks more complicated, but I can guarantee it's much faster. To plot colors, we use a color look-up table. This look-up table is a 768 (3x256) array. Each index of the table is really the offset index*3. The 3 bytes at each index hold the corresponding values (0-63) of the red, green, and blue components. This gives a total of 262144 total possible colors. However, since the table is only 256 elements big, only 256 different colors are possible at a given time. Changing the color palette is accomplished through the use of the I/O ports of the VGA card: Port 03C7h is the Palette Register Read port. Port 03C8h is the Palette Register Write port Port 03C9h is the Palette Data port Here is how to change the color palette: ; ax = palette index ; bl = red component (0-63) ; cl = green component (0-63) ; dl = blue component (0-63) mov dx,03C8h ; 03c8h = Palette Register Write port out dx,ax ; choose index mov dx,03C9h ; 03c8h = Palette Data port out dx,al mov bl,al ; set red value out dx,al mov cl,al ; set green value out dx,al mov dl,al ; set blue value Thats all there is to it. Reading the color palette is similar: ; ax = palette index ; bl = red component (0-63) ; cl = green component (0-63) ; dl = blue component (0-63) mov dx,03C7h ; 03c7h = Palette Register Read port out dx,ax ; choose index mov dx,03C9h ; 03c8h = Palette Data port in al,dx mov bl,al ; get red value in al,dx mov cl,al ; get green value in al,dx mov dl,al ; get blue value Now all we need to know is how to plot a pixel of a certain color at a certain location. Its very easy, given what we already know: ; bx = x coordinate ; ax = y coordinate ; dx = color (0-255) mov cx,bx ; copy bx to cx, to save it temporatily shl cx,8 ; shift left by 8, which is the same as ; multiplying by 2^8 = 256 shl bx,6 ; now shift left by 6, which is the same as ; multiplying by 2^6 = 64 add bx,cx ; now add those two together, whis is ; effectively multiplying by 320 add ax,bx ; finally add the x coord to this value mov es:[ax],dx ; copy color dx into memory location ; thats all there is to it Ok, we now know how to set up Mode 13h, set up the video buffer, plot a pixel, and edit the color palette. My next article will go on to show how to draw lines, utilize the vertical retrace for smoother rendering, and anything else I can figure out by that time... ::/ \::::::. :/___\:::::::. /| \::::::::. :| _/\:::::::::. :| _|\ \::::::::::. :::\_____\:::::::::::...........................................FEATURE.ARTICLE SMC Techniques: The Basics by mammon_ One of the benefits of coding in assembly language is that you have the option to be as tricky as you like: the binary gymnastics of viral code demonstrate this above all else. One of the viral "tricks" that has made its way into standard protection schemes is SMC: self-modifying code. In this article I will not be discussing polymorphic viruses or mutation engines; I will not go into any specific software protection scheme, or cover any anti-debugger/anti-disassembler tricks, or even touch on the matter of the PIQ. This is intended to be a simple primer on self-modifying code, for those new to the concept and/or implementation. Episode 1: Opcode Alteration ---------------------------- One of the purest forms of self-modifying code is to change the value of an instruction before it is executed...sometimes as the result of a comparison, and sometimes to hide the code from prying eyes. This technique essentially has the following pattern: mov reg1, code-to-write mov [addr-to-write-to], reg1 where 'reg1' would be any register, and where '[addr-to-write-to]' would be a pointer to the address to be changed. Note that 'code-to-write- would ideally be an instruction in hexadecimal format, but by placing the code elsewhere in the program--in an uncalled subroutine, or in a different segment--it is possible to simply transfer the compiled code from one location to another via indirect addressing, as follows: call changer mov dx, offset [string] ;this will be performed but ignored label: mov ah, 09 ;this will never be perfomed int 21h ;this will exit the program .... changer: mov di, offset to_write ;load address of code-to-write in DI mov byte ptr [label], [di] ;write code to location 'label:' ret ;return from call to_write: mov ah, 4Ch ;terminate to DOS function this small routine will cause the program to exit, though in a disassembler it at first appears to be a simple print string routine. Note that by combining indirect addressing with loops, entire subroutines--even programs--can be overwritten, and the code to be written--which may be stored in the program as data--can be encrypted with a simple XOR to disguise it from a disassembler. The following is a complete asm program to demonstrate patching "live" code; it asks the user for a password, then changes the string to be printed depending on whether or not the password is correct: ; smc1.asm ================================================================== .286 .model small .stack 200h .DATA ;buffer for Keyboard Input, formatted for easy reference: MaxKbLength db 05h KbLength db 00h KbBuffer dd 00h ;strings: note the password is not encrypted, though it should be... szGuessIt db 'Care to guess the super-secret password?',0Dh,0Ah,'