Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - saida

Pages: [1]
1
C / C++ /C# / Re: ASCII Matrix - C code
« on: October 18, 2006 »
Really nice work there!

2
ASM / Again, selfmodifying asm
« on: October 07, 2006 »
Ok, here I am again, talking about how much i like selfmodifying code segments :)

I have a bunch of sourcecodes in asm that uses this technique so save those extra bytes.
But i ran into problem when i wanted to use that code in my c-project.
This is because when i link my asm - i tell the linker to make my exe's code section READ/WRITE/EXECUTABLE
I couldnt find anyway to do this with my c compiler - and i didnt have the heart to do the asm code non-self-modifying (it would have cost me bytes!)

So i wrote this application to help me out. It takes 2 parameters: <filename> and <section-name-to-modify>
It opens the exe file (PE), and locates the section, and change permisions in it, so it will run with my asm code without crashing.

Here are the src for the program (if you wish to use any other permisions than mine). Precompiled exe: (changes to READ/WRITE/EXECUTABLE)
http://www.hd.chalmers.se/~Saida/dbf/section_perm.exe
Code: [Select]
/**
 * PE header section permision modifier.
 * Will set the section to READ/WRITE/EXECUTE
 * usable if you wrote a selfmodifying code segment in asm, and wishes
 * to use that outputed asm obj in you c program.
 * - Add this in a .bat file after you compiled your c project into a exe.
 * (only PE format supported)
 *
 * code by saida^titan^rebels
 * 2006-10-06
 * saida@lava.nu
 * http://saida.lava.nu
*/

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void showReadError()
{
printf("*** Could not read from file - is it a valid PE?\n");
}

void showWriteError()
{
printf("*** Could not write to file - in use - or disk full?\n");
}

void showUsage()
{
printf("Usage: section_perm.exe <filename> <section name to alter>\n");
}

void showOpenError()
{
printf("Could not open input file\n");
}

int main(int argc, char *argv[])
{
//section to modify
IMAGE_SECTION_HEADER modSection;

IMAGE_DOS_HEADER headerDos;
IMAGE_FILE_HEADER headerPE;

int i;
HFILE hFile;
unsigned char cBuf [5];
long sectionStartAddr;

if (argc<3) {
showUsage();
return 0;
}

// open file
hFile = _lopen(argv[1], OF_READWRITE);
if (hFile==0) {
showOpenError();
return 0;
}

//write some text on start.
printf("--------------------------------------------------------------------------------");
printf("*** Starting section_perm.exe\n");
printf("*** Opening file: \"%s\" and searching for \"%s\"\n", argv[1],  argv[2]);

//read dos header and check we read the correct amount of bytes
if (_lread(hFile, &headerDos, sizeof(IMAGE_DOS_HEADER))!=sizeof(IMAGE_DOS_HEADER)) {
printf("DOS_HEADER: ");
showReadError();
return 0;
}

//move filepointer to PE header start...
_llseek(hFile, headerDos.e_lfanew, FILE_BEGIN);


// Read PE signature and check we read the correct amount of bytes
memset(&cBuf, 0, 5);
if (_lread(hFile, &cBuf, 4)!=4) {
printf("PE_HEADER_SIGNATURE: ");
showReadError();
return 0;
}

// check read data to make sure this is a PE file
if (strcmp("PE", cBuf)!=0) {
printf("PE signature not found. This is not av valid PE file!");
return 0;
}


//read PE header data
if (_lread(hFile, &headerPE, sizeof(IMAGE_FILE_HEADER))!=sizeof(IMAGE_FILE_HEADER)) {
printf("PE_HEADER: ");
showReadError();
return 0;
}

//move pass the optional header
_llseek(hFile, headerPE.SizeOfOptionalHeader, FILE_CURRENT );

//now, we are on the first section address.
sectionStartAddr = headerDos.e_lfanew + sizeof(IMAGE_FILE_HEADER) + headerPE.SizeOfOptionalHeader + 4;

// step through all sections and search for the section the user entered.
for (i=0; i < headerPE.NumberOfSections; i++) {
if (_lread(hFile, &modSection, sizeof(IMAGE_SECTION_HEADER))!=sizeof(IMAGE_SECTION_HEADER)) {
printf("SECTION: ");
showReadError();
break;
}

// print current section
printf("%d: %s\n",i, modSection.Name);

if (strcmp(argv[2], modSection.Name)==0) {
modSection.Characteristics = modSection.Characteristics | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
_llseek(hFile, sectionStartAddr + (i * sizeof(IMAGE_SECTION_HEADER)), FILE_BEGIN);
if (_lwrite(hFile, &modSection, sizeof(IMAGE_SECTION_HEADER))==HFILE_ERROR) {
printf("SECTION: ");
showWriteError();
} else {
printf("Section was found and written to.\n" );
}

_lclose(hFile);
return 0;
}
}

// close the exe file
_lclose(hFile);
printf("Section was not found in file. Did you forget the leading dot?\n");
return 0;
}


I wasnt sure this was the right place to put this post, but we have been talking alot about stuff like this here lately .. so.. well. cheers!  :cheers:

3
ASM / Re: Making your exe smaller
« on: October 06, 2006 »
Probably - because im totaly lost ;)

4
ASM / Re: Making your exe smaller
« on: October 05, 2006 »
I dont think you have execute priveleges in ds. (only RW)
But i guess you could as well make that area RWE if you wanted to.
The main point here is to get rid of the overhead created, when you have two datasections (one from the asm obj, and one from the main c-program)
This is the only way me and auld got rid of it so far. Its weird, because i really do understand why we couldnt just merge our two data sections..

5
ASM / Re: plotting a pixel in dev cpp using inline asm
« on: October 04, 2006 »
thx ;)
Well, here is your carma relsoft
:cheers:

6
ASM / Making your exe smaller
« on: October 04, 2006 »
Normaly, you will create a data segment for your data, and a code segment for your code. This is however not the best way to go, if you are aiming for a really small exe.
If you are going to include a lib made in asm into your c project, you will get two data "sections". This drasticly increases the size of the final exe.
Look at the following code:
Code: [Select]
.data
 szMyString db "param1",0 ;7 bytes
.code
 push offset szMyString ; 5 bytes
 call myFunctionWithOneParameterPushed ; 5 bytes

(total of 7+5+5 = 17 bytes)
This is indeed a nice and structured way to program, but...

instead, look at this code:
Code: [Select]
.code
 call _ff ; 5 bytes
 szMyString db "param1",0 ;7 bytes
_ff:
 call myFunctionWithOneParameterPushed ; 5 bytes

(also 17 bytes, but we got rid of the data section)
When we call the label _ff, the processor automaticly pushes the return value to the stack. And guess what, that return value is the address to our string!
So this has eliminated the use of a data segment... or has it?
There is still one more problem to solve: how do we write to the "read-and-execute-only" code segment?
We could use the win api to unprotect the code segment in runtime - but that would be useless because of the extra bytes needed to do so.
Instead, you can link the masm code with:
\masm32\bin\Link /SUBSYSTEM:WINDOWS "myProgram.obj" /section:.text,RWE /MERGE:.rdata=.data /MERGE:.data=.text

If you want to use code that write to the code segment in a c-program, you will have to link your c program so it makes the code segment (.text) writable - dont forget that.
If your compiler fails to do this, just use PEExplorer or something like that to make your exe's code segment writable.

I hope this help someone out there, struggeling with huge mysterial overheads between his c-code, and asm code.
Sorry if something is unclear, i had to much coffee. ::)

7
ASM / Re: asm compos?
« on: October 04, 2006 »
Shockwave, dont overdo it, i personaly dont care if there is any price money in the compos - im just doing it for the fun (and to share source).  ;)

8
ASM / Re: asm compos?
« on: October 03, 2006 »
looking forward to it! :D

9
ASM / Re: plotting a pixel in dev cpp using inline asm
« on: October 03, 2006 »
wow thats really awesome - ive been looking for a sollution to get arround the at&t syntax
Relsoft, im giveing you some karma, as soon as i figure out how ;)

10
ASM / asm compos?
« on: October 02, 2006 »
I was just wondering if there has been or maybe going to be any compos on the board?
When i was learning asm and was chatting in #asm on efnet,
they had some really funny asm compos there, like 256 byte demos that had to boot from the bootsector of a floppy etc etc.
Also some really weird rules, like "all bytes in code must be viewable in notepad as a char" hehe ;)
It was a blast to see all the entrys people made. I think they had a months deadline or something like that for each compo.

If anyone else like compos, please drop a line ;)

11
ASM / Re: plotting a pixel in dev cpp using inline asm
« on: October 02, 2006 »
huh?
Does the line ".intel_syntax noprefix" make it possible to code inline asm wihtout the crazy at&t syntax?
(or didnt I simply understand anything)

12
ASM / Re: speech in 1k?
« on: September 15, 2006 »
Yes. Create a exe in c++ or download a program that can do this and open it in ollydbg. Could be hard to change settings.. i think you will have to use another CLSID and those are big.
Right now i have no clue at all how to change pitch and other settings for the voice, but it can be done in the speech config program by microsoft, so i guess its possible.
Sorry for not helping at all :)

13
ASM / Re: speech in 1k?
« on: September 14, 2006 »
ofcourse :)
If you wanna say "CLYDE"
then simply type a zero between each char. like this:

Code: [Select]
a db "C", 0, "L", 0, "Y", 0, "D", 0, "E", 0 ,0,0

dont forget to put two zeros at the end (its a widestring) (or was it four zeros)

hope its clear how to use it now.

EDIT:
OPS, i forgot to tell you taht you have to compile like i did with the midiSoundSystem (so the code section gets READ/WRITE/EXEC), if you dont do this the program will not work.
you can fix this by moving these lines to the .data section instead:
 ;szOle32
e dd 0

14
ASM / Re: speech in 1k?
« on: September 14, 2006 »
you are to kind   :D

15
ASM / speech in 1k?
« on: September 14, 2006 »
Ok, i will post some other funny code i wrote some time ago for the demo "hyptot1k" http://www.pouet.net/prod.php?which=23859
i compiled it to an obj, and linked the c demo auld wrote.

compile to an obj (and call the function named "speakIt" to start speaking)
\masm32\bin\ml /c /coff /nologo "speech1k.asm"

Please dont expect me to remember the code 100%, it was reverseEngineered from a c++ program by using ollyDgbg and a lot of free time :)
The speech text is in WIDECHAR... its probably smaller to write a fre lines of asm to WIDEN chars for you instead.
Hope someone find it usefull. Dont forget to link with ole32 and kernel32
It is only tested in windows xp sp2.
Enyoy!

Code: [Select]
.586p
.MODEL flat, stdcall

LoadLibraryA PROTO :DWORD
GetProcAddress PROTO :DWORD, :DWORD
CoInitialize PROTO :DWORD
CoCreateInstance PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

option casemap:none

.code
align 1

speakIt proc
pushad
xor edi, edi
mov esi, offset e
cmp dword ptr [esi], 0
jne @f

; invoke CoInitialize, null
push edi
call CoInitialize

; invoke  CoCreateInstance, addr b, 0, 7, addr d, addr e
push esi
push offset d
push 00000007h
push edi
push offset b
call CoCreateInstance

@@:
; invoke sapiFunction, asdasd, offsetToText, 1, 0
push edi
inc edi
push edi
push offset a
mov edx, [esi]
push edx
mov edx, [edx]

call dword ptr [edx+50h] ; speak!!!
popad
ret
speakIt endp

;blah1 CLSID and such...
b db 077h, 093h, 074h, 096h, 091h, 033h, 0d2h, 011h, 09eh, 0e3h, 000h, 0c0h, 04fh, 079h, 073h, 096h
;blah2 CLSID and such...
d db 074h, 0dfh, 044h, 06ch, 0b9h, 072h, 092h, 049h, 0a1h, 0ech, 0efh, 099h, 06eh, 004h, 022h, 0d4h

; stuff to say: uit says "music is chip-on.com"
a db "m",0,"u",0,"s",0,"i",0,"c",0," ",0,"i",0,"s",0," ",0;,;0,"s",0
db "c",0,"h",0,"i",0,"p",0," ",0,"o",0,"n",0,".",0,"c",0,"o",0,"m",0,0,0,0;

;szOle32
e dd 0
 
end

hope someone likes it - you dont see many speech in 1k nowdays :-\

Edit - Corrected Code Tags

16
ASM / Re: 1024b Midi Sound System (mss)
« on: September 14, 2006 »
thank you   :cheers:

17
ASM / 1024b Midi Sound System (mss)
« on: September 14, 2006 »
Finally decided to release it. I hope that someone will use it and make nice 1k demos with music! :)
Here are the source. Asm syntax is masm.
you will need this instrument list:
http://www.hd.chalmers.se/~Saida/titan/instruments.txt

Compiled version of the source:
http://www.hd.chalmers.se/~Saida/titan/mss.exe

you should add code to kick this off as a seperate thread with high priority...the music varies a lot with cpu load.

;
;  1024b Midi Sound System (mss)
;==============================================================================
;  @@ Programmed by: Martin Gustafsson - saida/titan^rebels
;  @@ Filename:      mss.asm
;  @@ Version:       3.1
;  @@ Date:          2006-09-14
;  @@ Web:           http://saida.lava.nu
;  @@ Mail:          saida at lava dot nu
;
;  If you use any of this code, please give me proper credits.
;
;  compile syntax:
;  \masm32\bin\ml /c /coff /nologo "mss.asm"
;  \masm32\bin\Link /SUBSYSTEM:WINDOWS /WS:AGGRESSIVE "mss.obj" /section:.text,RWE /MERGE:.rdata=.data /MERGE:.text=.data
;==============================================================================

; HISTORY
;==============================================================================
; Version 3.1 - Optimized code size. Fixed some bugs.
;             - Decided to go public with the midiSystem.   
;
; Version 3.0 - Big change! Now using 1 byte per tone only!
;             bit 7   = instrument (1 or 0)
;             bit 6-5 = length 0 1 2 3   
;             bit 4-0 = tone data.
;
; Version 2.0 - Some code cleanups.
;             - Optimized code size again. Tunes is now stored in another way.
;               Set bit7 of toneByte to 1/0
;             - Removed the data section. Exe now compiles to 1024b! \ :D /
;             - Rearanged code to compress better with com-packers.
;             - Fixed sleep bug between loops.
;             - Added support for 2 different instruments!       
;
; Version 1.0 - First release.
;             - One instrument support.
;             - two bytes per note.
;
;==============================================================================

; The 1024b Midi Sound System was used in these 1k demos:
; got balls?
; http://www.pouet.net/prod.php?which=18733
;
; rotor
; http://www.pouet.net/prod.php?which=17342

; MISC INFO
;==============================================================================
; Some information and thoughts behind the Init system:
; -----------------------------------------------------------------------------
; - First of all, let edi point to our data area, so we can use
;   edi instead of big memory adresses in the code.
; - Second, take usage of the fact, that eax is 0 when the program starts.
;   ok, this saves us what - 2 bytes... if you really done care about 2 bytes:
;   uncomment the "xor eax, eax" line at the start...
;
; Some information and thoughts behind the Player part:
; -----------------------------------------------------------------------------
; - Ok, edi is still used as the data pointer.
; - EDI and ESI does not change when calling the external dll functions, so
;   that is why I choosed ESI as a counter instead of ecx.
;   Now, i dont have to push and pop the counter register all the time! \ :D /
; - Another thing -> A byte is copied into AL from [EDI:ESI].
;   Then is the Length information is handled by BL register
;   The tone data in ah is then proccessed and pushed to the stack.
;   Next step is to see if the bit7 of AH is 1 or 0.
;   If bit7=0 then, instrument 0 is set. Else the instrument 1 is used.
;   The insrtument data is pushed to stack, and since we allready pushed the
;   tone data information to the stack, a double call to midi is done.
;   If a note byte would be 0, the song pattern loops.
;
; Limits etc
; -----------------------------------------------------------------------------
; The player does not play well if you have a high cpu load. This could be
; fixed (ofcourse it will cost you a lot of bytes) - by using GetTickCount
; instead of Sleep.     
;
; Dont forget!
; -----------------------------------------------------------------------------
; We are writing data to the code segment!
; If the code segment isnt set to be RWE - the program will not work!
; (RWE = Readable, Writable, Executable)
; If you use the compile lines at the top of this document, you should be fine.
;
; To get your final code smaller:
; -----------------------------------------------------------------------------
; rewrite the code so you set the instrument with the MOV instruction,
; rather than storing it in the fake-data-section, and then wasting bytes on
; getting that data.
; To do this: change the following lines.
; ORIGINAL LINE:
;                   mov bx, word ptr [edi-16+(2*ebx)]
; CHANGE TO:
;                   mov bx, word ptr [edi-8+(2*ebx)]
;
;
; ORIGINAL LINES:
;                   mov eax, [edi-8]                ; use instrument 0
;                   js @@bss_INSTRUMENT_DONE        ; Jump if bit7 is 1.
;                   mov eax, [edi-4]                ; else, use instrument 1
; CHANGE TO:
;                   mov eax, #dd_instrument_0       ; use instrument 0
;                   js @@bss_INSTRUMENT_DONE        ; Jump if bit7 is 1.
;                   mov eax, #dd_instrument_1       ; else, use instrument 1
;
; (and dont forget to remove the stuff in the fakedata section):
; @@bss_Instruments:                                REMOVE
;    dd 12594625      ; instrument index 0            REMOVE
;    dd 12594625      ; instrument index 1            REMOVE
;
;
; if you know you are only using instrument 0, you can remove this line to:
; and ebx, 00000011b                     
;==============================================================================

   .486
   .MODEL flat, stdcall
   
   includelib \masm32\lib\kernel32.lib ; Sleep call
   includelib \masm32\lib\winmm.lib    ; midi calls
   
   Sleep PROTO :DWORD
   midiOutOpen PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
   midiOutShortMsg PROTO :DWORD,:DWORD
   
   option casemap:none
   
.code

ProgramEntryPoint:
;------------------------------------------------------------------------------
; Initiate sound system
;------------------------------------------------------------------------------
    ;xor eax, eax                       ; uncomment this to loose 2 bytes :P
                                        ; eax should be zero at start.

    ; Setup esi/edi, so it points at data section
    ;==========================================================================       
        mov edi, offset bss_hMidi       ; use mov instead of lea. (smaller)

    ; Open midi device
    ;==========================================================================               
        push eax                        ; PUSH 0
        push eax                        ; PUSH 0
        push eax                        ; PUSH 0
        dec eax
        push eax                        ; PUSH 0xFFFFFFFF (MIDI_MAPPER)            
        push edi                        ; ( EDI is offset to hMidi )                  
        CALL midiOutOpen                ; call midiOutOpen
;------------------------------------------------------------------------------
; Playing part of sound system
;------------------------------------------------------------------------------

    ; Reset counter ESI that helps EDI to point at the music data
    ;==========================================================================
        ; xor eax, eax ; REMOVED! -> EAX should be zero if midiOutOpen was ok!
      ; if you are conserned by compatible/non-crashing demos. uncomment the
      ; "xor eax, eax" above...
    @@bss_RESET_SONG:               
        mov esi, edi                    ; set esi to point at fake data section
        LODSD                           ; Same as "add esi,4". (destoys eax)
                                        ; esi is now = offset "tone data"       
    ; Get new tone data from our array
    ;==========================================================================
    @@bss_LOAD_NEXT:               
        LODSB                           ; get BYTE from ES:ESI (the array)
        xchg ah, al   
        xor ebx,ebx                     ; set to zero before.
        add bl, ah                      ; if ah is zero, that means that we
                                        ; want to loop the song.
        jz @@bss_RESET_SONG             ; are we done? -> loop and play again.
       
        ; <get tone length in ms into ebx.>
        ; the data is in bl: ?TTx xxxx. after shr, its xxxx x?TT
        shr bl, 5                       
        ; remove additional ? data from byte (instrument could be 1)
        and ebx, 00000011b             

        ; extract millisecond sleep from length-array.
        mov bx, word ptr [edi-16+(2*ebx)]
       
    ; Setup eax for a call to midiOutShortMsg (to play a tone)
    ;==========================================================================
      ; here is the place where you can offset the midiNotes!
      ; (you can only use 0-31 midi notes)
      ;-----------------------
      ; add eax, SomeOffset
      ;-- OR:
      ; sub eax, SomeOffset
      ;-----------------------
        mov ecx, eax                    ; save toneData to ECX

        ; mask tone in eax with magic numbers..
        and ax, 0001111100000000b
        or eax, 00000000011111110010000010010001b       
        push eax                        ; push tone to play.          ##1 >---|
        push dword ptr [edi]            ; push handle to hMidi        ##1 >---|
                                        ;                                     |
    ; Was instrument should we use? 1 or 0?                                   |
    ;======================================================================== |
        xchg eax, ecx                   ; Restore toneData to eax.            |
        sahf                            ; pushes AH to flags.(SF=Bit7 in ah)  |
        mov eax, [edi-8]                ; use instrument 0                    |
        js @@bss_INSTRUMENT_DONE        ; Jump if bit7 is 1.                  |
        mov eax, [edi-4]                ; else, use instrument 1              |
                                        ;                                     |   
    ; Tell MIDI to change instrument for us.                                  |
    ;======================================================================== |
    @@bss_INSTRUMENT_DONE:              ;                                     |
        push eax                        ; push the instrument      ##2 >--|   |
        push dword ptr [edi]            ; push handle to hMidi     ##2 >--|   |   
        call midiOutShortMsg            ; <-------------------------------/   |
        call midiOutShortMsg            ; <-----------------------------------/

    ; Wait for the tone to play. Tone length is stored in BL
    ;==========================================================================
        push ebx                        ; ebx = sleep time
        call Sleep                      ; wait for tone to finish
         
        jmp @@bss_LOAD_NEXT             ; Repeat the procedure       

; END OF .CODE SECTION
;******************************************************************************

; size measure tool code (outputs size when compiling):
;------------------------------------------------------------------------------
   codelen  TEXTEQU  %($-ProgramEntryPoint)
   % echo <code_size> codelen bytes
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Faked .DATA section (makes exe smaller ...sometimes...)
; you can move this stuff to data section... but dont EVER move the data around
;------------------------------------------------------------------------------
;   music is stored like this (one byte per note):
;       ILLT TTTT
; bits  7654 3210
; where:
; I = Instrument index
; L = Length-of-note-index
; T = midi note
;
; SET THE BYTE TO -ZERO- TO LOOP FROM THE START OF THE SONG.

; lengths are in milliseconds.
@@bss_lengths:
    dw 240          ; lengh index 0.
    dw 1            ; lengh index 1
    dw 0            ; lengh index 2
    dw 0            ; lengh index 3

@@bss_Instruments:
    dd 12594625     ; instrument index 0
    dd 12594625     ; instrument index 1

@@bss_dataStart:
    bss_hMidi dd ?  ; handle to midi out.

; the song starts here (some test music i did):
;i
   db 10000101b;
   db 10101001b;play fast (use length index 1)
   db 10001100b
;a
   db 10000000b
   db 10101001b;play fast
   db 10001100b

;i
   db 10000101b
   db 10101001b;play fast
   db 10001100b
;a
   db 10000000b
   db 10101001b;play fast
   db 10001100b
;i
   db 10000101b
   db 10101001b;play fast
   db 10001100b
;a
   db 10000000b
   db 10101001b;play fast
   db 10001100b
   db 10000101b

; bam bam bam
   db 10000000b   
   db 10000010b
   db 10000100b

   db 00000000b ;loop from first note.
                           
end ProgramEntryPoint

Pages: [1]