Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Creating a binary file in different languages

by harangzsolt33 (Deacon)
on Jan 16, 2026 at 06:22 UTC ( [id://11167164]=CUFP: print w/replies, xml ) Need Help??

A few months ago I decided to do a little fun exercise (with AI's help). The little programs all do the same thing. The first one is written in Perl. The second one is written in AutoIt language, followed by QBASIC, then C, then JScript, Lua, PHP, Python, Bash, Excel VBA, and Linux x86 / x86_64 assembly.

Perl:

#!/usr/bin/perl -w use strict; use warnings; # Usage: STATUS = CreateHexFile(FILENAME, [STRINGS...]) sub CreateHexFile { defined $_[0] or return 0; my $F = shift; # Catch illegal characters in the file name $F =~ m/[\x00-\x1F*?|<>]{1}/ and return 0; # Join multiple arguments into one string my $hexstr = join('', map(defined $_ ? $_ : '', @_)); # Remove everything except hexadecimal digits $hexstr =~ tr|0-9A-Fa-f||cd; local *FILE; open(FILE, ">$F") or return 0; # Create binary file binmode FILE; # Convert hex string to a binary string and write it to the file. # If there is an odd number of hexadecimal digits in $hexstr, then # a zero digit is automatically added to the end at conversion. print FILE pack('H*', $hexstr); close FILE; return 1; } #################################################################### # Create a list of hexadecimal numbers from 00 to FF: my @numbers = map(sprintf('%.2X', $_), (0..255)); CreateHexFile('ASCII.BIN', @numbers);

AutoIt:

#include <File.au3> #include <Array.au3> #include <FileConstants.au3> #include <StringConstants.au3> #include <Constants.au3> #include <MsgBoxConstants.au3> #include <String.au3> $List = StringSplit(" 0f ff 00 c9 B8 EF 41 42 0A 0d 00 0c fe fe ", " + ") CreateHexFile("C:\DESKTOP\AUTOIT\Valami.bin", $List) MsgBox($MB_SYSTEMMODAL, "AutoIt Example", "Finished!") Exit ; USAGE: STATUS = CreateHexFile(FILENAME, [STRING_OR_LIST]) Func CreateHexFile($FileName, $Content) IF IsArray($Content) THEN $Content = _ArrayToString($Content, "") ENDIF MsgBox($MB_SYSTEMMODAL, "", ">>> " & $Content) $Content = StringRegExpReplace($Content, "[^0-9a-fA-F]+", "") local $output = "" local $Stop = StringLen($Content) local $x local $i For $i = 1 To $Stop Step 2 $output &= chr(Dec(StringMid($Content, $i, 2))) Next ;$StrContent = chr(0) & chr(255) & chr(151) ; StringToBinary(_HexT +oString($Content), $SB_ANSI) ;$HexContent = _StringToHex($StrContent) ;MsgBox($MB_SYSTEMMODAL, "", ">>> " & $HexContent & " " & $Content +) ;#if StringLen($HexContent) == StringLen($Content) Then ; ;Endif ; Create the file. Local $FileHandle = FileOpen($FileName, $FO_BINARY + $FO_OVERWRITE +) If $FileHandle = -1 Then MsgBox($MB_SYSTEMMODAL, "", "Error: Cannot create file - " & $ +FileName); Return 0 EndIf ; Write some data. FileWrite($FileHandle, $output) ; Close the handle returned by FileOpen. FileClose($FileHandle) EndFunc

QBASIC Language:

DEFINT A-Z DECLARE SUB CreateHexFile (FILENAME$, CONTENT$) ' These are hexadecimal digits that we will use to generate a list: X$ = "0123456789abcdef" ' This is what we will write to the file... MYLIST$ = "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f " ' We use two FOR loops to generate the rest of the list: FOR I = 2 TO 16 FOR J = 1 TO 16 MYLIST$ = MYLIST$ + MID$(X$, I, 1) + MID$(X$, J, 1) + " " NEXT J NEXT I CLS PRINT "This is the list of hexadecimal values that we will write to a +file:" PRINT PRINT MYLIST$ PRINT CreateHexFile "ASCIIBAS.BIN", MYLIST$ PRINT "File saved successfully." PRINT END ' ' This function creates a file in binary mode and writes some bytes in +to it. ' The CONTENT$ string should hold a string of hexadecimal numbers. ' The numbers will be grouped into pairs, and each pair will ' be converted to a byte and written to the file. ' Non-hexadecimal characters will be ignored. ' ' This function can be used to create small binary files (less than 2K +). ' SUB CreateHexFile (FILENAME$, CONTENT$) ' Create a file... OPEN FILENAME$ FOR OUTPUT AS #1 D = 0 ' We use this to count the hexadecimal digits FOR I = 1 TO LEN(CONTENT$) ' P = INSTR("0123456789ABCDEF", UCASE$(MID$(CONTENT$, I, 1))) ' IF P > 0 THEN ' D = D + 1 ' P = P - 1 ' The above code block calls UCASE$() function every time, ' but we can eliminate that by doing the following instead: ' P = INSTR("123456789abcdef0123456789ABCDEF", MID$(CONTENT$, I, + 1)) IF P > 0 THEN D = D + 1 P = P AND 15 IF D AND 1 THEN HI = P * 16 ELSE C$ = CHR$(HI + P) PRINT #1, C$; END IF END IF NEXT I ' Write last digit if there were an odd number of digits: IF D AND 1 THEN PRINT #1, CHR$(HI); CLOSE #1 END SUB

C Language:

#include <dir.h> #include <stdio.h> #include <string.h> /******************************************************************* // CATEGORY: File // FUNCTION: CreateHexFile // MODIFIED: 2025.9.28 // USAGE: int = CreateHexFile(*char FileName, *char HexString) // BRIEF: Creates a binary file and writes some bytes into it // // This function creates a binary file and writes bytes into it. // The function expects two string pointers, the first one pointing // to a file name and the second one pointing to a string containing // hexadecimal numbers. The function converts each hexadecimal // digit pair into a byte and writes the bytes to a file. // Non-hexadecimal digits in the arguments are ignored. // // If the file already exists, it will be deleted and replaced // with the new content. The function returns 1 on success or // zero if something went wrong. // // Note: Part of the original HexString will be overwritten with the // binary content, so this function destroys the second argument. // // Usage: int = CreateHexFile(char *FileName, char *HexString) */ int CreateHexFile(char *FileName, char *HexString) { /* This lookup table helps us convert hexadecimal digits to integers + quickly */ char *LUT = "ABCDEFGHIJ.......KLMNOPQ.........................KLMNOP +Q"; char c, hi, odd = 0; int i = 0, j = 0; FILE *f; if ((f = fopen(FileName, "wb")) == NULL) { fprintf(stderr, "Error: Cannot create file.\n"); return 0; } while ((c = HexString[i++]) != 0) { if (c < 48 || c > 102) continue; /* Non-hex char */ if ((c = LUT[c - 48]) < 65) continue; /* Non-hex char */ c -= 65; /* hex digit is now converted to an integer */ if ((odd = !odd) != 0) hi = c << 4; else HexString[j++] = hi | c; } /* Save last digit if there are odd number of hex digits */ if (odd) HexString[j++] = hi; /* Write converted binary data to file */ fwrite(HexString, j, 1, f); fclose(f); return 1; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { int i; char CharTable[513]; char *ptr = CharTable; /* Create a list of hexadecimal numbers from 00 to FF */ for (i = 0; i < 256; i++, ptr += 2) sprintf(ptr, "%.2X", i); CharTable[513] = 0; mkdir("C:\\TEMP"); CreateHexFile("C:\\TEMP\\ASCII.BIN", CharTable); }

JScript Language:

// Here we create a character set that is necessary for // writing bytes accurately in binary mode. // CHARSET = []; for (i = 0; i < 256; i++) CHARSET[i] = (i < 128 || i > 159) ? String.fromCharCode(i) : "\u20AC +\x81\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u015 +2\x8D\u017D\x8F\x90\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u +2122\u0161\u203A\u0153\x9D\u017E\u0178".charAt(i - 128); // Create list of hex numbers from 00 to FF // and write them to a file: HexList = []; for (i = 0; i < 256; i++) HexList[i] = (i < 16 ? "0" : "") + i.toString(16); CreateHexFile("ASCIIJS.BIN", HexList); //////////////////////////////////////////////////////////////////// // This function creates a new binary file and writes bytes into it. // The function expects a string argument or a list of strings // containing hexadecimal numbers. The function converts each // hexadecimal digit pair into a byte and writes the bytes // to a file. Non-hexadecimal digits in the arguments are ignored. // // If the file already exists, it will be deleted and replaced // with the new content. The function returns 1 on success or // zero if something went wrong. // // This function can have one or more arguments. // The first argument must be the file name, followed by a string // or list or several string arguments or lists. // // Usage: INTEGER = CreateHexFile(FILENAME, [STRING OR LIST]) // function CreateHexFile(FileName, Content) { Content = (typeof(Content) == "object") ? Content.join("") : Content + + ""; Content = Content.replace(/[^a-fA-F0-9]+/g, ""); if (Content.length & 1) Content += "0"; Content = Content.replace(/[a-fA-F0-9]{2}/g, function (n) { return CHARSET[parseInt(n, 16)]; }); try { var FSO = new ActiveXObject("Scripting.FileSystemObject"); F = FSO.CreateTextFile(FileName, 1, 0); F.Write(Content); F.Close(); return 1; } catch (e) {} return 0; }

Lua Language:

function CreateHexFile(FileName, Content) if type(Content) == "table" then Content = table.concat(Content, "") + end if type(Content) == "string" then Content = string.gsub(Content, "[^ +abcdefABCDEF%d]", "") end local file, err = io.open(FileName, "wb") if not file then return 0 end if (#Content % 2 == 1) then Content = Content .. "0" end local bytes = "" for i=1,#Content,2 do bytes = bytes .. string.char(tonumber(Content:sub(i, i+1), 16)) end file:write(bytes) file:close() return 1 end print("This program creates a file and write the following bytes into +it:\n") CharTable = "" for i = 0, 255 do CharTable = CharTable .. string.format("%02x ", i) end print(CharTable) if CreateHexFile("C:\\DESKTOP\\ASCIILUA.BIN", CharTable) then print("\nFile was written successfully.\n") else print("\nFile write failed.\n") end

PHP Language:

<?php // Create a list of hexadecimal numbers from 00 to FF. $hexstr = ""; for ($i = 0; $i < 256; $i++) $hexstr .= toHex($i) . " "; echo "This PHP program creates a file and writes the following charact +ers into it:<P><TT>"; echo $hexstr; $f = dirname(__FILE__) . "/ASCIIPHP.BIN"; CreateHexFile($f, $hexstr); echo "<P>DONE."; //////////////////////////////////////////////////////////////////// // USAGE: STRING = toHex(INTEGER) // This function converts an integer to a two-digit hexadecimal // number between 00 and FF. If the number is negative, the // function will return 00. If the number is 255 or greater, the // function will return FF. Anything in between will be converted // to a two-digit hexadecimal number. function toHex($c) { if ($c <= 0) return "00"; if ($c >= 255) return "ff"; return ($c < 16 ? "0" : "") . dechex($c | 0); } //////////////////////////////////////////////////////////////////// // USAGE: Status = CreateHexFile(FileName, HexString) // This function creates a binary file. The first argument must be // the name of the file. The second argument should be a string // that hold hexadecimal numbers. Each 2-digit number is // converted to a byte and written to the file. // Non-hex characters are ignored. // The function returns 1 on success or zero if an error occurred. function CreateHexFile($FileName, $Content) { $Status = 1; $Output = ""; // Remove all non-hexadecimal characters: $Content = preg_replace("/[^0-9a-fA-F]+/", "", $Content); // Make sure we have an even number of digits. if (strlen($Content) & 1) $Content .= "0"; // Convert hexadecimal numbers to bytes for ($i = 0; $i < strlen($Content); $i += 2) $Output .= chr(hexdec(substr($Content, $i, 2))); // Create file $f = fopen($FileName, "wb"); if (!fwrite($f, $Output)) $Status = 0; fclose($f); return $Status; } ?>

Python 2 and 3:

import os; import re; #################################################################### # USAGE: INTEGER = CreateHexFile(FILENAME, [CONTENT]) # This function creates a file and writes bytes in binary mode. # The bytes have to be provided as a string or list of # hexadecimal numbers. Each byte must be formatted as # a 2-digit hexadecimal number. # # The function returns 1 on success or 0 on error. # # The following example creates a file and writes "ABC" # NULL-terminated string into the file: # # CreateHexFile("testing.txt", " 41 42 43 00 ") # def CreateHexFile(FileName, Content = []): try: # Convert Content to a string and then # remove everything except hexadecimal digits: Content = re.sub("[^a-fA-F0-9]+", "", repr(Content)) # Line up the hexadecimal numbers in pairs # and convert them to integers: Content = map(lambda n: int(n, 16), re.findall('..', Content)) # Create the file and open for writing in binary mode: myfile = open(FileName, "wb") # Detect Python version by doing a simple division and # looking for the remainder. Python 2 always drops the # remainder when doing a division, so if the result # of 1/2 is zero, then the interpreter is Python 2. Python2 = (1 / 2) == 0 # Convert the list of integers to bytes # and write them to the file: if Python2: myfile.write("".join(map(chr, Content))) else: myfile.write(bytearray(Content)) myfile.close() except IOError: return 0 return 1 #CreateHexFile("C:\\DESKTOP\\TESTING456.BIN", " A0 01 CB C3 30 40 50 6 +0 70 80 90 A0 B0 C0 D0 E0 F0 FF 41 42 0D") CreateHexFile("ASCIIPY.BIN", ["CB", "C3", "00", "9A", "80", "41", "0D" +])

Bash:

###################################################################### # USAGE: CreateHexFile FILENAME [LIST] # This function creates a binary file and writes some bytes in it. # The first argument should be the full name of the file to be # created. The following arguments must be pairs of hexadecimal # digits which are converted to bytes and written to the file. # Finally, the function creates a global variable named $SUCCESS # and will write the number of bytes written into this variable. # If an error occurs, then this variable will hold an empty string. # If the function was called with only one argument, meaning that # no bytes were expected to be written, then the function will # create a file and leave it blank, and $SUCCESS will be set to 0. # # Example: # # CreateHexFile "myfile.tmp" 00 c3 9d 80 7e 92 23 ff 00 2c # if [[ $SUCCESS ]]; then # echo "$SUCCESS bytes written successfully." # else # echo "Failed to create file." # fi # function CreateHexFile { SUCCESS='' local filename="$1" local bytecount=0 local byte local hex shift # Create the file > "$filename" # File exists? if [[ -f $filename ]]; then # Make sure file length is zero at this point: local filelen=$(stat --printf="%s" "$filename") if [[ $filelen -gt 0 ]]; then return 0 fi SUCCESS=0 # Convert hexadecimal numbers to bytes # and write them to the file: for hex in "$@"; do # Remove everything except hexadecimal digits hex=$(printf '%s' "${hex//[![:xdigit:]]}") for (( i=0; i<${#hex}; i+=2 )); do # Take two digits at a time byte="\\x${hex:i:2}" # Write it to the file one byte at a time printf "$byte" >> "$filename" # Count number of bytes sent to the file bytecount=$((bytecount + 1)) done done if [[ $bytecount -gt 0 ]]; then local filelen=$(stat --printf="%s" "$filename") if [[ $filelen -eq $bytecount ]]; then SUCCESS=$filelen fi fi else echo "Error: Cannot create file - $filename" >&2 fi } $MyList = " 00 01 02 03 04 05 06 07 " CreateHexFile "ASCIIBASH.BIN" $MyList

Excel VBA:

' This VBA macro works in Excel; it will not work in ' Google Sheets, OpenOffice, or GNumeric. ' Insert the following into an empty new Excel spreadsheet and ' paste the following two macros. Then run the two that begin with ' the word "Action" Sub Action_CreateCharTable() HexDigits = "0123456789ABCDEF" ' Fill in values from 00 to FF For Column = 1 To 16 For Row = 1 To 16 CellName = Chr(Column + 64) & Row HexValue = "'" & Mid(HexDigits, Row, 1) & Mid(HexDigits, C +olumn, 1) Range(CellName).Value = HexValue Next Next ' Align values in the center of each cell Range("A1:P16").Select With Selection .HorizontalAlignment = xlCenter .VerticalAlignment = xlBottom .WrapText = False .Orientation = 0 .AddIndent = False .IndentLevel = 0 .ShrinkToFit = False .ReadingOrder = xlContext .MergeCells = False End With Range("A1").Select End Sub Sub Action_SaveFile() ' Collect hexadecimal numbers from cells into a string HexString = "" For Row = 1 To 16 For Column = 1 To 16 CellName = Chr(Column + 64) & Row HexString = HexString & Range(CellName).Value Next Next Call CreateHexFile("ASCII.BIN", HexString) End Sub ' USAGE: Call CreateHexFile(FileName, StringContent) Sub CreateHexFile(FileName, Content) ' Create the file Set FSO = CreateObject("Scripting.FileSystemObject") Set F = FSO.CreateTextFile(FileName, 1, 0) If VarType(Content) = vbString Then D = 0 ' Number of hexadecimal digits we have encounter +ed Output = "" ' Binary string output For I = 1 To Len(Content) ' The following line captures digits and uppercase and low +ercase letters (A-F) and ' outputs a number between 0 and 16. If it's zero, then th +at means ' the input character was not a hexadecimal digit. P = InStr("123456789abcdef0123456789ABCDEF", Mid(Content, +I, 1)) If P > 0 Then D = D + 1 P = P And 15 If D And 1 Then ' Store high nibble in U U = P * 16 Else ' Combine high nibble and low nibble U + P Output = Output & Chr(U + P) End If End If Next ' Write last digit if there were an odd number of digits: If D And 1 Then Output = Output & Chr(U) F.Write Output End If F.Close End Sub

Finally, in linux x86 / x86_64:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; File Name: CreateHexFile.asm ; ; This program creates a file called asciiasm.bin in the current ; directory and writes 256 bytes into it. It's a simple example ; program written in assembly language for Linux to be compiled ; with nasm. This program is designed so it can be built either ; into an x86 or x86_64 executable without requiring any changes ; to the source code. ; ; To build a 64-bit Linux executable, enter the following ; commands in the terminal: ; ; nasm -f elf64 -o CreateHexFile.o CreateHexFile.asm ; ld -s -no-pie -z noseparate-code CreateHexFile.o -o CreateHexFi +le ; strip -s CreateHexFile ; ; To build a 32-bit executable, run the following commands: ; ; nasm -f elf32 -o CreateHexFile.o CreateHexFile.asm ; ld -s -no-pie -z noseparate-code -m elf_i386 CreateHexFile.o -o + CreateHexFile ; strip -s CreateHexFile ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; %if __BITS__ == 64 %define _AX RAX %define _BX RBX %define _CX RCX %define _DX RDX %define _SI RSI %define _DI RDI %define _BP RBP %macro EXIT 1 ; EXIT requires 1 argument MOV RDI,%1 ; Error code will be placed into RDI MOV RAX,60 ; Sys_exit is function #60 in 64-bit kernel SYSCALL %endmacro %else %macro EXIT 1 ; EXIT requires 1 argument MOV EBX,%1 ; Error code will be placed into EBX MOV EAX,1 ; Sys_exit is function #1 in 32-bit kernel INT 0x80 %endmacro %define _AX EAX %define _BX EBX %define _CX ECX %define _DX EDX %define _SI ESI %define _DI EDI %define _BP EBP %endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PROGRAM DATA SECTION ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SECTION .data FileName: DB "asciiasm.bin", 0 Msg_success: DB "File created successfully.", 10, 0 Msg_failure: DB "File could not be created.", 10, 0 Msg_welcome: DB 10, 10, "The following bytes will be written to a file: ", 10, + 10 HexCode: DB "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f", 10 DB "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f", 10 DB "20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f", 10 DB "30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f", 10 DB "40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f", 10 DB "50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f", 10 DB "60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f", 10 DB "70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f", 10 DB "80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f", 10 DB "90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f", 10 DB "a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af", 10 DB "b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf", 10 DB "c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf", 10 DB "d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df", 10 DB "e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef", 10 DB "f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff", 10, 0 SECTION .text GLOBAL _start _start: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PROGRAM BEGINS HERE ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This part of the source code is identical for both x86 and ; x86_64 builds. The '_' in front of the registers stands for ; either an 'E' or an 'R' which will be substituted by nasm ; when it is time to compile the code. MOV _SI,Msg_welcome ; Inform the user about what we are doing CALL PrintText MOV _SI,HexCode MOV _DI,_SI CALL Hex2Str ; Convert hexadecimal digits into binary bytes ; Hex2Str will place the length of string into _DX and the string ; pointer will be left in _DI, which is exactly where ; CreateFile expects them to be: MOV _SI,FileName CALL CreateFile JNC Success_Exit ; CreateFile sets carry flag on error MOV _SI,Msg_failure CALL PrintText ; Print error message EXIT 1 Success_Exit: MOV _SI,Msg_success CALL PrintText ; Print success message EXIT 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CATEGORY: File ; FUNCTION: CreateFile ; CREATED: 2026.1.23 ; PLATFORM: Linux x86 or x86_64 ; DESCR: Creates a binary file ; ; This function creates a new file (if the file already exists, ; then it deletes its contents) and writes some bytes into it. ; ; DS:_SI <= Pointer to ASCIIZ file name ; DS:_DI <= Pointer to data to be written ; _DX <= Number of bytes to write ; _CX => Number of bytes written ; CF => Carry Flag will be set on error ; Modifies: _CX,Flags ; CreateFile: PUSH _AX PUSH _BX PUSH _DX PUSH _SI PUSH _DI %if __BITS__ == 64 PUSH R14 PUSH R13 PUSH R12 PUSH R11 ; I entered the following into Google search: ; Write assembly code that creates a file and writes some bytes into i +t and results in a linux elf64 executable. ; This gave me a starting point, so then I could change things around +a bit... ; Now, whoever designed the x86_64 Linux kernel decided that sys calls + will have completely ; different numberings and arguments are to be passed in different reg +isters than x86. ; That person should be put in jail!! ; First of all, we will save the values of RDI and RDX in other regist +ers. MOV R14,RDI MOV R13,RDX ; Create the file. MOV RAX,2 ; The function number for sys_open is 2 in 64- +bit mode. ; The kernel expects the following argument(s): ; RDI <= Pointer to the ASCIIZ string that holds the file name. ; RSI <= The file open mode ; RDX <= The permission flags MOV RDI,RSI MOV RSI,65 ; CREATE=1 | TRUNCATE=64 MOV RDX,0o644 ; File permissions: rw-r--r-- SYSCALL ; SYSCALL always modifies RAX, RCX, and R11 MOV R12,RAX ; Save the file descriptor in R12 ; The file descriptor will be a negative number if sys_open failed +. SHL RAX,1 ; Shift highest bit of RAX into CF JC CreateFile_Error_x64 ; Jump if RAX was a negative number ; Write bytes to the file. MOV RAX,1 ; The function number for sys_write is 1 in 64 +-bit mode. ; The 64-bit kernel expects arguments in RDI, RDX, and RSI: MOV RDI,R12 ; Load file descriptor from R12 MOV RDX,R13 ; Load number of bytes to write from R13 MOV RSI,R14 ; Load data pointer from R14 SYSCALL ; SYSCALL always modifies RAX, RCX, and R11 XCHG RDX,RAX ; RDX <= Save number of bytes written ; Close the file. MOV RAX,3 ; The function number for sys_close is 3 in 64 +-bit mode. MOV RDI,R12 ; Load the file descriptor from R12 SYSCALL ; SYSCALL always modifies RAX, RCX, and R11 MOV RCX,RDX ; RCX <= Load number of bytes written SHL RDX,1 ; Is this a negative number? JNC CreateFile_Exit_x64 CreateFile_Error_x64: XOR _CX,_CX ; Zero bytes written STC CreateFile_Exit_x64: POP R11 POP R12 POP R13 POP R14 %else ; 32-bit version of the code follows next: ; Create and Open File MOV EAX,5 ; The function number for sys_open is 5 in 32- +bit mode. ; The 32-bit kernel expects arguments in EBX=filename, ECX=flags, +and EDX=mode. MOV EBX,ESI ; EBX <= File name MOV ESI,EDX ; Save number of bytes to write in ESI tempora +rily MOV ECX,65 ; CREATE=64 | WRITEONLY=1 MOV EDX,0o644 ; File permissions: rw-r--r-- INT 0x80 ; The kernel returns the file descriptor returned in EAX. MOV EBX,EAX ; EBX <= Save file descriptor ; The file descriptor will be a negative number if sys_open failed +. SHL EAX,1 ; Shift highest bit of EAX into CF JC CreateFile_Error_x86 ; Jump if EAX was a negative number MOV EAX,4 ; The function number for sys_write is 4 in 32 +-bit mode. ; The 32-bit kernel expects arguments in EBX=file_descriptor, ECX= +buffer, and EDX=length. ; EBX is already set from above MOV ECX,EDI MOV EDX,ESI ; Restore number of bytes to write from ESI INT 0x80 MOV ECX,EAX ; Save number of bytes written in ECX MOV EAX,6 ; The function number for sys_close is 6 in 32 +-bit mode. INT 0x80 ; Expects file descriptor in EBX which is alre +ady set. MOV EAX,ECX SHL EAX,1 ; Shift highest bit of EAX into CF JNC CreateFile_Exit ; Exit normally if it was a positive nu +mber. CreateFile_Error_x86: XOR ECX,ECX STC %endif CreateFile_Exit: POP _DI POP _SI POP _DX POP _BX POP _AX RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CATEGORY: Stdio ; FUNCTION: PrintText ; MODIFIED: 2026.1.22 ; PLATFORM: Linux x86 or x86_64 ; DESCR: Prints an ASCIIZ string to stdout ; ; This function prints an ASCIIZ string to stdout. ; ; DS:_SI <= Pointer to ASCIIZ string ; Modifies: None ; PrintText: PUSHF PUSH _SI PUSH _DI PUSH _DX PUSH _AX CALL StrLen %if __BITS__ == 64 MOV RDI,1 ; File descriptor 1 is STDOUT MOV RAX,1 SYSCALL %else PUSH ECX MOV ECX,ESI ; ECX <= Pointer to text MOV EBX,1 ; File descriptor 1 is STDOUT MOV EAX,4 INT 0x80 POP ECX %endif POP _AX POP _DX POP _DI POP _SI POPF RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CATEGORY: String ; FUNCTION: StrLen ; MODIFIED: 2026.1.22 ; PLATFORM: x86 or x86_64, OS independent ; DESCR: Returns the length of an ASCIIZ string ; ; This function finds the terminating NULL character at the end of ; a string and returns the length of string in EDX. ; ; DS:_SI <= Pointer to ASCIIZ string ; _DX => Length of string ; Modifies: _DX,Flags ; StrLen: PUSH _SI PUSH _CX PUSH _AX XOR _DX,_DX ; Reset byte counter. MOV _CX,_SI NEG _CX DEC _CX ; ECX <= maximum allowed length of string CLD ; We will be reading in forward direction StrLen_Loop: LODSB TEST AL,AL JE StrLen_EndOfString INC _DX LOOP StrLen_Loop StrLen_EndOfString: POP _AX POP _CX POP _SI RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CATEGORY: String ; FUNCTION: Hex2Str ; MODIFIED: 2026.1.22 ; PLATFORM: x86 or x86_64, OS independent ; DESCR: Converts hexadecimal digits to binary string ; ; This function converts an ASCIIZ string of hexadecimal numbers ; to binary string. The numbers are grouped into pairs from left to ; right and then each pair is converted to a byte. Non-hexadecimal ; characters are ignored. If there's an odd number of hexadecimal ; digits in the input string, then the function pretends that there ; is a zero at the end completing the last byte. ; ; DS:_SI <= Pointer to ASCIIZ string containing hex digits ; ES:_DI <= Pointer to destination memory area ; _DX => Number of bytes written ; Modifies: _DX,Flags ; Hex2Str: PUSH _SI PUSH _DI PUSH _AX XOR _DX,_DX ; Reset byte counter. CLD ; Read/write operations move in forward direction. ; We will use the high 4 bits of AH to store the upper nibble of ; the byte. AH will be set to 255 when it is empty or uninitialized. Hex2Str_Reset: MOV AH,255 Hex2Str_Loop: LODSB TEST AL,AL JE Hex2Str_EndofString CMP AL,'0' JB Hex2Str_Loop ; Skip non-hex char CMP AL,'f' JA Hex2Str_Loop ; Skip non-hex char CMP AL,'9' JA Hex2Str_NonDigit SUB AL,'0' JMP Hex2Str_SaveValue Hex2Str_NonDigit: OR AL,32 SUB AL,'a' CMP AL,5 JA Hex2Str_Loop ; Skip non-hex char ADD AL,10 Hex2Str_SaveValue: CMP AH,255 JE Hex2Str_StoreHigh ; Got second hex digit. Now, merge them together and save byte. OR AL,AH STOSB INC _DX JMP Hex2Str_Reset Hex2Str_StoreHigh: SHL AX,12 ; Transfer low 4 bits from AL into high 4 bit +s of AH JMP Hex2Str_Loop ; Stored first hex digit. Hex2Str_EndofString: ; Save last byte if odd number of digits. CMP AH,255 JE Hex2Str_Exit MOV AL,AH STOSB INC _DX Hex2Str_Exit: POP _AX POP _DI POP _SI RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://11167164]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2026-02-09 01:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.