| 订阅 | 在线投稿
分享
 
 
 

Win32的512字节Intro

来源:互联网网民  宽屏版  评论
2006-12-17 09:28:40

Win32的512字节Intro

Win32的512字节Intro Writing a 512b intro for Win32. upi/throb Since Windows was released no one could imagine that it's possible to make a 4kb intro for it. Time went on, and now coders write a lot of 4kb intros for Windows and some of them are even accelerated! This is cool enough, but not so cool as writing 512b for Win32 and accel! I guess now some boneheads say: "whata fuck u talking about?! 512b for Windows and accel? It's impossible! The init part alone in my 4kb is about 1kb, and you say you've written 512b, freak...." and so on.. and so on... Relax guys, it's possible and now I'll show how I've done it. First of all, a win32 program has imports of the system functions it uses. Normally imports are inserted in the .idata section of PE and look like: _dlldb "zlo.dll",0_funkdb "MightyFunc",0_Import:dd 0; Ptr to original "thunk"dd 0; Time stampdd 0; Forwarder chaindd _dll; Ptr to DLL namedd _funk; Ptr to replaced "thunk"(..code by TAD)

...so importing only one function is about 20 bytes + sizeof(_dll) + sizeof(_funk) !!! Oh, shit! We need over 20 system funcs => the min size it takes = 20*20 = 400 bytes for nothing!!! Now let's eliminate this injustice. Step one. Importing functions by import table sux! It's much better to load .dll dynamically and import interesting functions, like that: push dword _dllcall LoadModuleApush eaxpush dword _funccall GetProcAddressAmov dword [MightyFunc],eax

Step two. Let's look carefully at opengl32.dll. Exported funcs in it are sorted alphabetically, and ordinals are set from 1 to 369! Number of Standart OpenGL funcs are fixed and all additions are made by GL_EXTENTIONS => we can garantee that ordinals will be the same on all Microsoft implementations of OpenGL, so we can import opengl funcs by ordinals. It works for all windows versions. Put opengl functions` ordinals in a table and organize a loop: mov edi,dword _openglAPImov esi,dword _openglORDxor eax,eax antiloop:push edxlodsbor al,aljs lexitadd ebx,eaxpush ebxpush edxcall GetProcAddressAstosdpop edxjmp antiloop lexit:

Here in edx - opengl32.dll handle, edi - APItable, so we can use the smallest possible (for our use) calling opcode: call [ebp + num]

or we can define a struct and use: call [ebp].glEnable

esi is the address of an opengl ord deltas; to decrease the size we use a bytes array, but the maximum opengl ord(369) does not fit into the size of one byte => we compute the delta value for each pair of ords: db 15 - 0;glBlendFunc(ord 15)db 52 - 15;glColor4ubv(ord 52)db 81 - 52;glEnable(ord 81)db 166 - 81;glLoadIdentity(ord 166)db 183 - 166;glMatrixMode(ord 183)db 0xff

The last byte - 0xff shows that our loop must stop. OK. We convert 20 to 1 byte + small loop. that's good. "Hey! But in order to init Windows except of opengl32.dll functions we also need kernel32.dll, user32.dll and gdi32.dll functions!" an experienced reader says. =) That's right, and now we are going to kill these imports. =) Unlike opengl functions other system functions change their ords in different versions of Windows. =( So we can't use it =( "What do u know, hardcoder?" It took a long time for me to get an answer... Step one. We no longer need GDI32's SwapBuffers and SetPixelFormat! This funcs are in opengl32.dll, but have slightly different names: wglSwapBuffers, wglSetPixelFormat. It's little bit undocumented, and I thought those funcs tooks params like clones in GDI32, and I was right! So we add those funcs to our ords table. ChoosePixelFormat is also no longer needed! We can set the pixel format to 4 or 8. And in w98 and wME, it works correctly! (w2k - not =( push byte 0push byte 4;4 - doublebuffered opengl with zbuffer!!(even on Matrox!!=)push ebxcall wglSetPixelFormat

Step two. Xmmm. So we've killed GDI32 imports... kernel32, user32 remaining... Let's look at opengl32 a litle bit more carefully, and we'll find a strange table at the .code section start. I don't know how the fuck Microsoft compiles its progs, but this table is a table to RAW addreses of functions of the current Windows version, that opengl32 uses! Good sign! =) In this table I've found some glu32.dll funcs, GetProcAddress, GetMessage, GetDC and CreateWindowEx! Just grab the functions addresses in the apitable and call them! Step three. In my intro I use gluNewQuadric, gluQuadricTexture, gluSphere, these funcs do not exist in opengl32.dll table.. =( "Ha.. ha.. and what do you now?" Funny thing, but if you load opengl32.dll it'll automatically load glu32.dll, and a more funny thing: what is HMODULE? It's a simple RAW offset in memory to the module image! "..and so what?!" The module alignment is 65536 bytes => get (from our "magic table") the GLU32 function that lies in the first 65536 bytes of the GLU32 module, then clear the lower 16 bits, and we get a GLU32 HMODULE! Simple, isn't it?! Imports conclusion. We replace all 20 imports with only one from opengl32.dll, that lies in the first 65536 bytes, get HMODULE, then using "magic table" we get kernel32, user32 API, using GetProcAddress get opengl32 API, if we have opengl32 we have glu32 => get it HMODULE and using GetProcAddress get its API. Now we have all we need! All useful imports are in our APItable, let's code an intro! =) First of all let's create a window..... Conclusion. I pack an intro with nowadays standard approach - make a small (35 bytes) DOS .com stub that saves PE .exe to disk then runs it, after running deletes it, end exits. then I pack .com with "apack by Jibbz". Big credit to TAD for writing a perfect binPE asm stub which I use. Tnx. WindowsXP notes. WindowsXP is a very strange thing =) first of all, it uses CreateWindowExW instead of CreateWindowExA. next, in opengl32.dll missed DllInitalize function => all ordinals decreased by one. next(very, very strange), in gdi32.dll function SetPixelFormat sets flag that indicate "is SetPixelFormat been called, or not?", and then checks it in GetPixelFormat, so wglCreateContext did't work with our approach (setting pixel format by using wglSetPixelFormat). i've made XP version, but there is nonstable section =) i set gdi32.dll flag directly by writing in memory. In the bonus pack you'll find the complete sources and versions. Happy coding. upi/throb (yomoma@rambler.ru) Small 512b coding FAQ: Q: "Hey! What about registering the window class?!"

A: It's easy: for smaller size we use one of the standard classes - "EDIT". Q: "..and about keypress and sync?!"

A: We get keypresssings and time values from GetMessage. Q: "Please explain your texture generation algorithm."

A: I get the texture from opengl32.dll code =)

转贴说明-------------------------------

我其实对DEMO和INTRO并不在行,只停留在欣赏阶段,只是觉得这么好的东西不拿出来和大家分享很说不过去。一般来说开发它们的都是较为“和平”的黑客,很多以前都是Cracker后改作图形编程,他们都是汇编和算法的行家,大部分作品及源代码在www.scene.org可以下载,建议看看VIP2这个DEMO,这个网站论坛上N人挺多喔!

 
特别声明:以上内容(如有图片或视频亦包括在内)为网络用户发布,本站仅提供信息存储服务。
 
Win32的512字节Intro Win32的512字节Intro Writing a 512b intro for Win32. upi/throb Since Windows was released no one could imagine that it's possible to make a 4kb intro for it. Time went on, and now coders write a lot of 4kb intros for Windows and some of them are even accelerated! This is cool enough, but not so cool as writing 512b for Win32 and accel! I guess now some boneheads say: "whata fuck u talking about?! 512b for Windows and accel? It's impossible! The init part alone in my 4kb is about 1kb, and you say you've written 512b, freak...." and so on.. and so on... Relax guys, it's possible and now I'll show how I've done it. First of all, a win32 program has imports of the system functions it uses. Normally imports are inserted in the .idata section of PE and look like:   _dll db "zlo.dll",0 _funk db "MightyFunc",0 _Import: dd 0 ; Ptr to original "thunk" dd 0 ; Time stamp dd 0 ; Forwarder chain dd _dll ; Ptr to DLL name dd _funk ; Ptr to replaced "thunk"(..code by TAD) ...so importing only one function is about 20 bytes + sizeof(_dll) + sizeof(_funk) !!! Oh, shit! We need over 20 system funcs => the min size it takes = 20*20 = 400 bytes for nothing!!! Now let's eliminate this injustice. Step one. Importing functions by import table sux! It's much better to load .dll dynamically and import interesting functions, like that:   push dword _dll call LoadModuleA push eax push dword _func call GetProcAddressA mov dword [MightyFunc],eax Step two. Let's look carefully at opengl32.dll. Exported funcs in it are sorted alphabetically, and ordinals are set from 1 to 369! Number of Standart OpenGL funcs are fixed and all additions are made by GL_EXTENTIONS => we can garantee that ordinals will be the same on all Microsoft implementations of OpenGL, so we can import opengl funcs by ordinals. It works for all windows versions. Put opengl functions` ordinals in a table and organize a loop:   mov edi,dword _openglAPI mov esi,dword _openglORD xor eax,eax antiloop: push edx lodsb or al,al js lexit add ebx,eax push ebx push edx call GetProcAddressA stosd pop edx jmp antiloop lexit: Here in edx - opengl32.dll handle, edi - APItable, so we can use the smallest possible (for our use) calling opcode:   call [ebp + num] or we can define a struct and use:   call [ebp].glEnable esi is the address of an opengl ord deltas; to decrease the size we use a bytes array, but the maximum opengl ord(369) does not fit into the size of one byte => we compute the delta value for each pair of ords:   db 15 - 0 ;glBlendFunc(ord 15) db 52 - 15 ;glColor4ubv(ord 52) db 81 - 52 ;glEnable(ord 81) db 166 - 81 ;glLoadIdentity(ord 166) db 183 - 166 ;glMatrixMode(ord 183) db 0xff The last byte - 0xff shows that our loop must stop. OK. We convert 20 to 1 byte + small loop. that's good. "Hey! But in order to init Windows except of opengl32.dll functions we also need kernel32.dll, user32.dll and gdi32.dll functions!" an experienced reader says. =) That's right, and now we are going to kill these imports. =) Unlike opengl functions other system functions change their ords in different versions of Windows. =( So we can't use it =( "What do u know, hardcoder?" It took a long time for me to get an answer... Step one. We no longer need GDI32's SwapBuffers and SetPixelFormat! This funcs are in opengl32.dll, but have slightly different names: wglSwapBuffers, wglSetPixelFormat. It's little bit undocumented, and I thought those funcs tooks params like clones in GDI32, and I was right! So we add those funcs to our ords table. ChoosePixelFormat is also no longer needed! We can set the pixel format to 4 or 8. And in w98 and wME, it works correctly! (w2k - not =(   push byte 0 push byte 4 ;4 - doublebuffered opengl with zbuffer!!(even on Matrox!!=) push ebx call wglSetPixelFormat Step two. Xmmm. So we've killed GDI32 imports... kernel32, user32 remaining... Let's look at opengl32 a litle bit more carefully, and we'll find a strange table at the .code section start. I don't know how the fuck Microsoft compiles its progs, but this table is a table to RAW addreses of functions of the current Windows version, that opengl32 uses! Good sign! =) In this table I've found some glu32.dll funcs, GetProcAddress, GetMessage, GetDC and CreateWindowEx! Just grab the functions addresses in the apitable and call them! Step three. In my intro I use gluNewQuadric, gluQuadricTexture, gluSphere, these funcs do not exist in opengl32.dll table.. =( "Ha.. ha.. and what do you now?" Funny thing, but if you load opengl32.dll it'll automatically load glu32.dll, and a more funny thing: what is HMODULE? It's a simple RAW offset in memory to the module image! "..and so what?!" The module alignment is 65536 bytes => get (from our "magic table") the GLU32 function that lies in the first 65536 bytes of the GLU32 module, then clear the lower 16 bits, and we get a GLU32 HMODULE! Simple, isn't it?! Imports conclusion. We replace all 20 imports with only one from opengl32.dll, that lies in the first 65536 bytes, get HMODULE, then using "magic table" we get kernel32, user32 API, using GetProcAddress get opengl32 API, if we have opengl32 we have glu32 => get it HMODULE and using GetProcAddress get its API. Now we have all we need! All useful imports are in our APItable, let's code an intro! =) First of all let's create a window..... Conclusion. I pack an intro with nowadays standard approach - make a small (35 bytes) DOS .com stub that saves PE .exe to disk then runs it, after running deletes it, end exits. then I pack .com with "apack by Jibbz". Big credit to TAD for writing a perfect binPE asm stub which I use. Tnx. WindowsXP notes. WindowsXP is a very strange thing =) first of all, it uses CreateWindowExW instead of CreateWindowExA. next, in opengl32.dll missed DllInitalize function => all ordinals decreased by one. next(very, very strange), in gdi32.dll function SetPixelFormat sets flag that indicate "is SetPixelFormat been called, or not?", and then checks it in GetPixelFormat, so wglCreateContext did't work with our approach (setting pixel format by using wglSetPixelFormat). i've made XP version, but there is nonstable section =) i set gdi32.dll flag directly by writing in memory. In the bonus pack you'll find the complete sources and versions. Happy coding. upi/throb (yomoma@rambler.ru) Small 512b coding FAQ: Q: "Hey! What about registering the window class?!" A: It's easy: for smaller size we use one of the standard classes - "EDIT". Q: "..and about keypress and sync?!" A: We get keypresssings and time values from GetMessage. Q: "Please explain your texture generation algorithm." A: I get the texture from opengl32.dll code =) 转贴说明------------------------------- 我其实对DEMO和INTRO并不在行,只停留在欣赏阶段,只是觉得这么好的东西不拿出来和大家分享很说不过去。一般来说开发它们的都是较为“和平”的黑客,很多以前都是Cracker后改作图形编程,他们都是汇编和算法的行家,大部分作品及源代码在www.scene.org可以下载,建议看看VIP2这个DEMO,这个网站论坛上N人挺多喔!
󰈣󰈤
 
 
 
>>返回首页<<
 
 热帖排行
 
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
©2005- 王朝网络 版权所有