I am writing a program that looking for files with the extension ".fly". It displays the names of the founded files, but when I try to use FindFirstFile and FindNextFile, my program crashes. I have tried with FindFirstFileA (ANSI Version of the function) , but my code crashes too. Please, give me a example of code if it's possible.
Please, thanks for your answers. Here's my source code written in FASM Assembly
format pe console 4.0
include 'C:\fasm\INCLUDE\WIN32AX.INC'
; Declare a macro to make buffers
macro dup label,lcount
{ forward
label#:
common
repeat lcount
forward
db 0
common
end repeat }
.code
main:
explore_directoy:
invoke FindFirstFile,file_extension, FIND_STRUCT ; find the first *.fly
mov dword [find_handle], eax
find_more_files:
cmp eax, 0
je exit
call show_file
findnextfile:
invoke FindNextFile, dword [find_handle], FIND_STRUCT
jmp find_more_files
show_file:
invoke MessageBox, NULL, addr msg, addr msg_caption, MB_OK ; Easy way of outputing the text
;invoke MessageBox, NULL, addr cFileName, addr msg_caption, MB_OK
ret
exit:
invoke ExitProcess, 0
datazone:
end_msg db 'End of program', 0
msg db 'File founded', 0
msg_caption db 'Assembly program...', 0
file_extension db '*.fly', 0
find_handle dd 0 ; handles/other stuff..
FIND_STRUCT: ; find structure used with searching
dwFileAttributes dd 0
ftCreationTime dd 0,0
ftLastAccessTime dd 0,0
ftLastWriteTime dd 0,0
nFileSizeHigh dd 0
nFileSizeLow dd 0
dwReserved0 dd 0
dwReserved1 dd 0
dup cFileName, 256 ; found file buffer
dup cAlternate, 14
.end main
Your .text section isn't writable. Change
.code
to
section '.text' readable writable executable
Data should go into the .data section, not the .code section. If your assembler supports uninitialized data (all values defined as ?), then it should go into the .data? section (this is the equivalent of a bss (block started by symbol) section used in some other assemblers).
Related
In a disassembled dll (by IDA), I reached an array, which is commented as an array of int (but it may be of byte):
.rdata:000000018003CC00 ; int boxA[264]
.rdata:000000018003CC00 boxA dd 0 ; DATA XREF: BlockPrepXOR+5FC↑r
.rdata:000000018003CC04 db 0Eh
.rdata:000000018003CC05 db 0Bh
.rdata:000000018003CC06 db 0Dh
.rdata:000000018003CC07 db 9
.rdata:000000018003CC08 db 1Ch
.rdata:000000018003CC09 db 16h
.rdata:000000018003CC0A db 1Ah
.rdata:000000018003CC0B db 12h
.rdata:000000018003CC0C db 12h
.rdata:000000018003CC0D db 1Dh
.rdata:000000018003CC0E db 17h
.rdata:000000018003CC0F db 1Bh
Can I interpret the data as
{000000h, E0B0D09h, 1C161A12h, ..} or
{0, 90D0B0Eh, 121A161Ch, ...} or
{00h,00h,00h,00h, 0Eh, 0Bh, ..} ?
From the comment (from IDA), can you confirm that the array ends at CC00h + 253*4 = D01Fh ? I have another array starting at D020h:
.rdata:000000018003D01D db 0F9h ; ù
.rdata:000000018003D01E db 0A2h ; ¢
.rdata:000000018003D01F db 3Fh ; ?
.rdata:000000018003D020 array4_1248 db 1 ; DATA XREF: BlockPrepXOR+39A↑o
.rdata:000000018003D021 db 2
.rdata:000000018003D022 db 4
.rdata:000000018003D023 db 8
That's just the AES decryption's T8 matrix as described in this paper.
You can easily identify it by looking for the DWORDs values on Google (e.g. this is one of the results).
So that's just data for an AES decryption function.
Note also that the interpretation of a sequence of bytes as a sequence of multi-byte data (WORDs, DWORDs, QWORDs, and so on) depends on the architecture.
For x86, only the little-endian interpretation is correct (this is your case 2) but data may undergo arbitrary manipulations (e.g. it can be bswapped) so, when looking on Google, always use both the little and the big-endian versions of the data.
It's also worth noting that IDA can interpret the bytes as DWORDs (type d twice or use the context menù), showing the correct value based on the architecture of disassembled binary.
I have some FAT32 structure output:
bytes_per_sector 0x200
sectors_per_cluster 0x8
reserved_sector_count 0x780
FATtable_count 0x2
root_entry_count 0
hidden_sector_count 0x38
total_sectors_32 0xf17fc8
FATtable_size_32 0x3c40
root_cluster 0x2
fat_info 0x1
backup_BS_sector 0x6
Ok, assume to this information, I jump over reserved_sector_count and get the FAT32 table. #1920 - is offset from te begining - 0x780.
fat32Table #1920
cluster0 ffffff8
cluster1 ffffffff
cluster2 fffffff
cluster3 fffffff
Ok, assume to FATtable_size_32 and FATtable_count I jump over and get to the Data Region at the position #16777216 from the begining. This is the 0 cluster, as I understand. Cluster consists of 8 sectors by 512 byte each. First Directory named "F" - is volume. Second "HELLO.TXT" is a file. DirectoryEntry size of 32 byte.
name #16777216 46 [F ]
ext [ ]
attrib 8
NTreserved 0
CrtTimeTenth 0
createtime 0
createdate 0
accessdate 0
clusterhigh 0
modifiedtime 81e3
modifieddate 4ace
clusterlow 0
filesize 0
name #16777216 48 [HELLO ]
ext [TXT]
attrib 20
NTreserved 18
CrtTimeTenth 5c
createtime 82ca
createdate 4ace
accessdate 4ace
clusterhigh 0
modifiedtime 82d4
modifieddate 4ace
clusterlow 3
filesize 24
Next, I want to find data according to "hello.txt" file. I see clusterlow= 0x03. When I jump to next cluster (+4096 byte) and see data of my file.
name #16781312 This is test
But I don't get how does clusterlow help me to find it? What clusters ffffff8, ffffffff, fffffff in FAT32 table? How to find source data according to all this stuff?
#tilz0R, thanks for a link, but I have already read a doc from MS. And more.
I just get that at the DataRegion (after reserved sectors and FAT32 table) we begin with the cluster2, and clusterlow=0x03 means that source data located in the next cluster3 which is +4096 byte lower than cluster2.
It was easier to understand when I add one more file on a disk and see that first file located in the cluster3 and the second - cluster4.
What I'm really stuck on is how I'm supposed to make this loop properly I tried doing every combination for each branch but it either never stops or it stops at the wrong number of loops (supposed to stop after amount of values in RPN_START). I even tried what I did in a previous lab which also failed to work so I'm completely lost as to how I'm supposed to get this program to loop. I understand that the RPN_OUT is the end pointer of the array so I tried putting RPN_START with CPY to compare the values but doing that made it stop after one loop. So I don't know at all which branch I'm supposed to use. Any help/tips/advice would be greatly appreciated. Thank you so much!
ORG DATA
;RPN_IN FCB $06,$03,$2F,$04,$2A,$02,$2B ; 63/4*2+=10
;RPN_IN FCB $05,$01,$02,$2B,$04,$2A,$2B,$03,$2D ; 512+4*+3-
;RPN_IN FCB $02,$03,$2A,$05,$2A,$02,$2F,$01, $2B ; ( ( (2 * 3) * 5) / 2) + 1
RPN_IN FCB $11,$10,$2F,$15,$2A ; ( (11 / 10) ) * 15
RPN_OUT RMB 1
RPN_START FDB RPN_IN ; Pointer to start of RPN array
RPN_END FDB RPN_OUT ; Pointer to end of RPN array
ANSWER RMB 1
TEMP FCB $00
ORG PROG
Entry: ; KEEP THIS LABEL!!
LDS #PROG
LDX #RPN_IN
LOOP:
TFR X,A
LDAA X
...
PSHA
RET:
INX
CPX #RPN_OUT
BNE LOOP
PULA
STAA ANSWER
So I got the following (as an example):
0x00000001000022c4 db "Apple", 0
0x0000000100002347 db "Ducks", 0
In a procedure it refers to Apple as such:
lea rcx, qword [ds:0x1000022c4] ; "Apple"
Now I like this string to say Ducks and so I tried to modify assembly instruction by saying:
lea rcx, qword [ds:0x100002347]
However when I apply it says something like:
lea rcx, qword [ds:0x2ace]
Why does it do it?
I was able to fix it by going into the hex editor find the hex value, look how much the offset was off and correct it. But it felt cumbersome.
Hopper Disassembler V3 is great tool to do reverse engineering. I have the same problem too. Here is my solution. My Demo arch is x86_64:
00000001000174a6 mov rsi, qword [ds:0x1004b3040] ; #selector(setAlignment:)
When you see this, it's not mean you could modify the address(0x1004b3040) to whatever you want.
Exactly the assemble code is:
00000001000174a6 movq 0x49bb93(%rip), %rsi ## Objc selector ref: setAlignment:
That means you should convert target address '0x49bb93'
The formula is 0x1004b3040 - 00000001000174a6 - 7 = 0x49bb93
So if you want to modify the address to 100002347 'Ducks', you should follow this formula and find the byte length of your instruction, my is '7'
In my demo I'd like to modify the #selector(setAlignment:) to #selector(setHidden:), So I have to convert it with the formula below:
0x1004b2238 - 0x1000174a6 - 7 = 0x49ad8b
So modify the hex code with 48 8b 35 8b ad 49 00, press 'command + shift + H' to show hex editor in Hopper.
Here comes some demo pictures:
Before my work
After my work
My english is not very good, so welcome to reply.
I have to write a program for my Assembly class that allows the user to enter his/her full name and the program then utilizes and array to store the characters and print them in the following order: "LastName", "Middle"(Optional and can have more than one middle name" "First". I have gotten my program to almost do this except it prints out a '$' at the start of the Last name. I have tried incrementing the index (bx) but then it gives me a garbled output. I am fairly new to assembly so please bear with me. I am thinking my macros might be interfering with my output when I increment the index. Also please bear with my formatting. I can never transfer code correctly. Thanks in Advance!
Here is my code:
;This Program Reads in a user's full name and prints out the results in the format
'Lastname', 'Middle'(Optional), First using an array.
include pcmac.inc
.MODEL SMALL
.586 ;Allows Pentium instructions. Must come after .MODEL
.STACK 100h
.DATA
MAXBUF EQU 100
GetBuf DB MAXBUF
GetCnt DB ?
CharStr DB MAXBUF DUP (?)
Message DB 'Enter your full name',10,13,'$'
Message2 DB 'Here is your name in the correct format', 10,13,'$'
Count DB 0
.CODE
Array PROC
_Begin
_PutStr Message
_GetStr GetBuf
mov bl, GetCnt
sub bh,bh
FindLast:
cmp [CharStr+bx],32
je SeperateLast
dec bx
inc Count ;Counter to record how long the lastname is
jmp FindLast
SeperateLast:
mov [CharStr+bx],'$'
_PutStr Message2
jmp Printlast
FirstName:
_PutCh ',',32 ;Add comma and space for readability
_PutStr CharStr ;Print up to the inputted dollar sign
_PutCh 10,13
jmp Done
Printlast:
cmp Count,0
je FirstName
_PutCh[CharStr+bx] ;Print Last Name Character by Character
inc bx
dec Count
jmp Printlast
Done:
_Exit 0
Array ENDP
END Array
From what I can see in your code, you seem to be properly finding the last name. Since the space before the last name represents the end of the First and Middle name it makes sense to replace the space with the $ sign just before the last name. Since BX is the offset of the dollar sign you just put in, you should increment BX by one to skip over it. You then need to decrement the Count variable by 1 as well.
This code:
mov [CharStr+bx],'$'
_PutStr Message2
jmp Printlast
Should probably be something like:
mov [CharStr+bx],'$'
inc bx
dec Count
_PutStr Message2
jmp Printlast