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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|---|