Colex 0 #1 Posted June 14, 2010 (edited) SpriteAsm Extrator de Sprites Programador: Alex Santos (Colex) Linguagem de Programação: Assembly (Compilado em GCC 4.2.2) Como funciona: Basta colocar o ficheiro Tibia.spr na pasta do SpriteAsm.exe, abrir o programa e esperar que extraia para a pasta Sprites. Detalhes da Aplicação: Esta aplicação não tem o objetivo de substituir outras aplicações (e.g.: a ferramenta feita por blackdemon). O SpriteAsm foi feito com o objetivo de alcançar um tempo de extração rapido para o disco (e não para a memoria volátil). Por esse motivo foi desenvolvido em Assembly. Para testar comparei com a ferramente desenvolvida por Troopers (que extrai para o disco). A ferramenta do troopers demorou 3 minutos e 30 segundos a extrair enquanto que o SpriteAsm demorou 1 minuto. Ainda é algum tempo, porém foi 3.5 vezes mais rápido. O código poderia ser optimizado, mas por ser apenas uma "brincadeira" para estudo fiquei satisfeito. As sources estão disponiveis, deixei alguns comentários no código Sources: ################################## ## SpriteAsm ## ## Developed by Alex Santos ## ## (Colex) ## ################################## .data READ_FLAG: .asciz "rb" WRITE_FLAG: .asciz "wb" SPRITES_DIR: .asciz "Sprites" SPRITES_FILE: .asciz "Tibia.spr" EMPTY_FILE: .asciz "%d.bmp" PREVIOUS_DIR: .asciz "cd .." BITMAP_HEADER_INFO: .long 0x4D42, 150, 0, 54, 40, 32, 32, 1, 24, 0, 96, 2835, 2835, 0 BITMAP_HEADER_SIZE: .long 2, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, 4, 8, 0 START_STRING: .asciz "SpriteAsm (Developed by Alex Santos)\n\n-- Started Extracting... " END_STRING: .asciz "[Done]\n\nEnded Extraction\n" .globl _main ################################## ## WRITE_BYTES ## ################################## _write_bytes: #paramaters: file pointer, value, size #Epilogue pushl %ebp movl %esp, %ebp ######### pushl 8(%ebp) pushl $1 pushl 16(%ebp) leal 12(%ebp), %eax pushl %eax call _fwrite addl $16, %esp #Prologue leave ret ################################## ################################## ## CREATE_EMPTY_SPRITE ## ################################## _create_empty_sprite: #parameter: sprite number #Epilogue pushl %ebp movl %esp, %ebp pushl %ebx pushl %esi pushl %edi subl $255, %esp ######## leal -255(%ebp), %eax #Generate the sprite name pushl 8(%ebp) pushl $EMPTY_FILE pushl %eax call _sprintf addl $12, %esp #Open the file in write mode pushl $WRITE_FLAG leal -255(%ebp), %eax pushl %eax call _fopen addl $8, %esp movl %eax, %ebx #Write the BMP header leal BITMAP_HEADER_SIZE, %esi leal BITMAP_HEADER_INFO, %edi write_header: movl (%esi), %eax cmp %eax, 0 je write_header_end pushl %eax pushl (%edi) pushl %ebx call _write_bytes addl $12, %esp addl $4, %edi addl $4, %esi jmp write_header write_header_end: #Fill the sprite with transparent color movl $0, %esi pushl $3 pushl $0xFF00FF pushl %ebx write_pixels: call _write_bytes addl $1, %esi cmp $1024, %esi jne write_pixels addl $12, %esp pushl $2 pushl $-96 pushl %ebx call _fseek #addl $12, %esp #Return the file pointer (through %eax) movl %ebx, %eax #Prologue movl %ebp, %esp subl $12, %esp popl %edi popl %esi popl %ebx leave ret ################################## ################################## ## READ_SPRITES ## ################################## _read_sprites: #parameter: file pointer #Epilogue pushl %ebp movl %esp, %ebp subl $32, %esp pushl %edi pushl %esi pushl %ebx ######### #Ignore header informations (except the sprites count) pushl $0 pushl $4 pushl 8(%ebp) call _fseek addl $12, %esp #Read how many sprites are in the file pushl 8(%ebp) pushl $1 pushl $2 leal -4(%ebp), %eax pushl %eax call _fread addl $16, %esp movl -4(%ebp), %edi #Read all the sprites to a file movl $1, -32(%ebp) read_sprite: pushl -32(%ebp) call _create_empty_sprite addl $4, %esp movl %eax, %ebx #pushl %esi #pushl $TEST_STRING1 #call _printf #Read the next sprite's pointer movl -32(%ebp), %eax imull $4, %eax addl $6, %eax pushl $0 pushl %eax pushl 8(%ebp) call _fseek addl $12, %esp pushl 8(%ebp) pushl $1 pushl $4 leal -4(%ebp), %eax pushl %eax call _fread addl $16, %esp movl -4(%ebp), %eax addl $3, %eax pushl $0 pushl %eax pushl 8(%ebp) call _fseek addl $12, %esp #Read the sprites size (number of bytes) pushl 8(%ebp) pushl $1 pushl $2 leal -8(%ebp), %eax pushl %eax call _fread addl $16, %esp #Read the pixels subl %esi, %esi read_pixels: movl -8(%ebp), %eax cmp %eax, 0 je close_sprite #Read the number of transparent pixels pushl 8(%ebp) pushl $1 pushl $2 leal -12(%ebp), %eax pushl %eax call _fread addl $16, %esp #Ignore the transparent pixels movl -12(%ebp), %eax addl %eax, %esi imull $3, %eax pushl $1 pushl %eax pushl %ebx call _fseek addl $12, %esp #Read the number of colored pixels pushl 8(%ebp) pushl $1 pushl $2 leal -16(%ebp), %eax pushl %eax call _fread addl $16, %esp movl -8(%ebp), %eax subl $4, %eax movl %eax, -8(%ebp) ###################################################### #Bitmap "mirror's" the image, so we need to calculate# #the original position of the pixel # ####### y = (32 - (P / 32)) * 96 ################### calculate_pos: movl %esi, %eax subl %edx, %edx movl $32, %ecx idiv %ecx addl $1, %eax subl %eax, %ecx imull $96, %ecx movl %ecx, -4(%ebp) ####### x = (P % 32) * 3 ####### movl %esi, %eax subl %edx, %edx movl $32, %ecx idiv %ecx imull $3, %edx ####### pos = x + y + 54 ####### addl %edx, -4(%ebp) addl $54, -4(%ebp) pushl $0 pushl -4(%ebp) pushl %ebx call _fseek addl $12, %esp ################################### ################### #Write the colored pixels to the file write_colored_pixels: movl -16(%ebp), %eax cmp %eax, 0 je read_pixels #Read RGB bytes read_rgb: pushl 8(%ebp) pushl $1 pushl $1 leal -20(%ebp), %eax pushl %eax call _fread addl $4, %esp leal -24(%ebp), %eax pushl %eax call _fread addl $4, %esp leal -28(%ebp), %eax pushl %eax call _fread addl $16, %esp #Write RGB bytes to the file pushl $1 pushl -28(%ebp) pushl %ebx call _write_bytes addl $8, %esp pushl -24(%ebp) pushl %ebx call _write_bytes addl $8, %esp pushl -20(%ebp) pushl %ebx call _write_bytes addl $12, %esp addl $1, %esi movl -8(%ebp), %eax subl $3, %eax movl %eax, -8(%ebp) movl -16(%ebp), %eax subl $1, %eax movl %eax, -16(%ebp) #Verify if needs to recalculate the position movl %esi, %eax subl %edx, %edx movl $32, %ecx idiv %ecx cmp %edx, 0 je calculate_pos jmp write_colored_pixels #Close the sprite's file close_sprite: pushl %ebx call _fclose addl $4, %esp addl $1, -32(%ebp) cmp -32(%ebp), %edi jne read_sprite #Prologue movl %ebp, %esp subl $12, %esp popl %ebx popl %esi popl %edi leave ret ################################## ############################## ## MAIN ## ############################## _main: #Epilogue pushl %ebp movl %esp, %ebp ######### pushl $START_STRING call _printf #Open the Tibia.Spr pushl $READ_FLAG pushl $SPRITES_FILE call _fopen #Exit if couldn't open the Tibia.spr cmp %eax, 0 je prologue mov %eax, %ebx #Create the Sprites directory pushl $SPRITES_DIR call _chdir #If it already exists, don't create cmp %eax, 0 je do_no_create call _mkdir call _chdir do_no_create: pushl %ebx call _read_sprites #Close the Tibia.spr pushl %ebx call _fclose pushl $END_STRING call _printf pushl $PREVIOUS_DIR call _system #Prologue prologue: leave ret ################################## Download (executável): http://www.4shared.com/file/Dn5sMsiL/SpriteAsm.html Recapitulando: Isto foi apenas objeto de estudo, pode ser usado por quem quiser da forma que quiser. Cumprimentos, Alex Santos Edited June 14, 2010 by Colex Share this post Link to post Share on other sites
River 3 #2 Posted June 14, 2010 Prefiro o editor do Black Demon! BRINKS! kkkkkkkk Muito rox, cara! Sempre ajudando a galera ai! E tudo com código aberto! XD Valeu pelo post! Abraço Share this post Link to post Share on other sites
Baxnie 8 #3 Posted June 14, 2010 Assembly sempre me atraiu, mas é baixo o nível. Ao mesmo tempo que te da maior liberdade e controle, é bem mais trabalhoso de se programar. Não entendi muito bem qual a grande otimização de seu código. Mas já pensou se o motivo do seu código ser 3 vezes mais rápido do que o do Troopers não é devido a algum 'defeito' no código dele? Share this post Link to post Share on other sites
Colex 0 #4 Posted June 14, 2010 @Up A razão é pela que voce mesmo citou, é de baixo nivel, da um maior liberdade de controlo. Assim eu posso optmizar o código para ser mais rápido. Porem, normalmente, assembly não compensa. C é rápido e mais facil de programar, então por uma diferença de segundos (dependendo do código) mais vale programar em C. (ou outra linguagem) Eu só fiz isto porque acho interessante a linguagem, oferece um desafio. Share this post Link to post Share on other sites
Fixthow 33 #5 Posted June 14, 2010 Grande Utilitário, vai ajudar muitas pessoas Share this post Link to post Share on other sites
Baxnie 8 #6 Posted June 14, 2010 Já brinquei um pouco com ASM, copiando código dos outros, para meu benefício. É bem divertido. :X Porém realmente não compensa, não consigo imaginar utilidade no dia-a-dia de um programador. Somente acho que é útil para compreender como realmente funciona a rotina de um programa, entender para evitar bugs como de buffer overflow. Share this post Link to post Share on other sites
Dark Skyllen 7 #7 Posted June 15, 2010 Já brinquei um pouco com ASM, copiando código dos outros, para meu benefício. É bem divertido. :X Porém realmente não compensa, não consigo imaginar utilidade no dia-a-dia de um programador. Somente acho que é útil para compreender como realmente funciona a rotina de um programa, entender para evitar bugs como de buffer overflow. Na verdade quando se pensa em desempenho é muito util na vida de um programador. O preço a se pagar por isso é essa linguagem tão cheia de nós. Share this post Link to post Share on other sites
EcL 3 #8 Posted June 15, 2010 Muito bom, assembly rula mesmo, e pra quem disse que não serve pra nada, está totalmente errado. Principalmente quando se fala em exploits. Share this post Link to post Share on other sites
Anywhere 0 #9 Posted November 17, 2010 Engraçado, esses dias eu estava lendo tutoriais de Assembly, como o Colex disse oferece um desafio =D Quem sabe em breve eu não me aventure em algum utilitário AOEKOAKEAE Mas creio que irei me apronfundar em C++ msm '-' Obrigado pelo tópico Colex, isso gera até um incentivo *-* Share this post Link to post Share on other sites
flipagenor 0 #10 Posted August 25, 2012 Até hoje, não consegui entender um simples código em Assembly, sequer! Share this post Link to post Share on other sites