mirror of
				https://github.com/lordfriky/web-cfw-loader.git
				synced 2025-10-30 18:59:40 +00:00 
			
		
		
		
	Merge pull request #77 from zhangjiantao/patch-1
fix: payloadType not defined
This commit is contained in:
		
						commit
						c721ed37c1
					
				
							
								
								
									
										480
									
								
								main.js
									
									
									
									
									
								
							
							
						
						
									
										480
									
								
								main.js
									
									
									
									
									
								
							| @ -1,240 +1,240 @@ | ||||
| function logOutput(...message) { | ||||
|   document.getElementById("output").innerHTML = document.getElementById("output").innerHTML + message.join(" ") + "<br>"; | ||||
| } | ||||
| 
 | ||||
| function clearLog() { | ||||
|   document.getElementById("output").innerHTML = ""; | ||||
| } | ||||
| 
 | ||||
| async function getPayloadList(){ | ||||
|   return fetch("payloads/payloads.json") | ||||
|   .then((response) => { | ||||
|     if(!response.ok) | ||||
|       throw new Error(response.status); | ||||
|     return response.json(); | ||||
|   }) | ||||
|   .then((data) => { | ||||
|     return data.payloads; | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| (async () => { | ||||
|   const payloadSelect = document.getElementById("payloadSelect"); | ||||
|   let payloadList; | ||||
|   try { | ||||
|     payloadList = await getPayloadList(); | ||||
|      | ||||
|   } catch (error) { | ||||
|     logOutput("There was a problem retreiving the payload list. Error: " + error); | ||||
|     return; | ||||
|   } | ||||
|   payloadList.forEach((payload) => { | ||||
|     const payloadOption = document.createElement("option"); | ||||
| 
 | ||||
|     payloadOption.value = payload.path; | ||||
|     payloadOption.innerHTML = payload.name + " " + payload.version; | ||||
| 
 | ||||
|     payloadSelect.appendChild(payloadOption); | ||||
|   }); | ||||
| 
 | ||||
| })() | ||||
| 
 | ||||
| async function getPayload(payloadSrc){ | ||||
| 	return fetch(payloadSrc) | ||||
| 	.then((response) => { | ||||
| 		if(!response.ok) | ||||
| 			throw new Error(response.status); | ||||
| 		return response.arrayBuffer(); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| const intermezzo = new Uint8Array([ | ||||
|   0x44, 0x00, 0x9F, 0xE5, 0x01, 0x11, 0xA0, 0xE3, 0x40, 0x20, 0x9F, 0xE5, 0x00, 0x20, 0x42, 0xE0, | ||||
|   0x08, 0x00, 0x00, 0xEB, 0x01, 0x01, 0xA0, 0xE3, 0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0xA0, 0xE1, | ||||
|   0x2C, 0x00, 0x9F, 0xE5, 0x2C, 0x10, 0x9F, 0xE5, 0x02, 0x28, 0xA0, 0xE3, 0x01, 0x00, 0x00, 0xEB, | ||||
|   0x20, 0x00, 0x9F, 0xE5, 0x10, 0xFF, 0x2F, 0xE1, 0x04, 0x30, 0x90, 0xE4, 0x04, 0x30, 0x81, 0xE4, | ||||
|   0x04, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0x1A, 0x1E, 0xFF, 0x2F, 0xE1, 0x20, 0xF0, 0x01, 0x40, | ||||
|   0x5C, 0xF0, 0x01, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x01, 0x40 | ||||
| ]); | ||||
| 
 | ||||
| const RCM_PAYLOAD_ADDRESS = 0x40010000; | ||||
| const INTERMEZZO_LOCATION = 0x4001F000; | ||||
| const PAYLOAD_LOAD_BLOCK = 0x40020000; | ||||
| 
 | ||||
| function createRCMPayload(intermezzo, payload) { | ||||
|   const rcmLength = 0x30298; | ||||
| 
 | ||||
|   const intermezzoAddressRepeatCount = (INTERMEZZO_LOCATION - RCM_PAYLOAD_ADDRESS) / 4; | ||||
| 
 | ||||
|   const rcmPayloadSize = Math.ceil((0x2A8 + (0x4 * intermezzoAddressRepeatCount) + 0x1000 + payload.byteLength) / 0x1000) * 0x1000; | ||||
| 
 | ||||
|   const rcmPayload = new Uint8Array(new ArrayBuffer(rcmPayloadSize)) | ||||
|   const rcmPayloadView = new DataView(rcmPayload.buffer); | ||||
| 
 | ||||
|   rcmPayloadView.setUint32(0x0, rcmLength, true); | ||||
| 
 | ||||
|   for (let i = 0; i < intermezzoAddressRepeatCount; i++) { | ||||
|     rcmPayloadView.setUint32(0x2A8 + i * 4, INTERMEZZO_LOCATION, true); | ||||
|   } | ||||
| 
 | ||||
|   rcmPayload.set(intermezzo, 0x2A8 + (0x4 * intermezzoAddressRepeatCount)); | ||||
|   rcmPayload.set(payload, 0x2A8 + (0x4 * intermezzoAddressRepeatCount) + 0x1000); | ||||
| 
 | ||||
|   return rcmPayload; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function bufferToHex(data) { | ||||
|   let result = ""; | ||||
|   for (let i = 0; i < data.byteLength; i++) | ||||
|     result += data.getUint8(i).toString(16).padStart(2, "0"); | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| async function write(device, data) { | ||||
|   let length = data.length; | ||||
|   let writeCount = 0; | ||||
|   const packetSize = 0x1000; | ||||
| 
 | ||||
|   while (length) { | ||||
|     const dataToTransmit = Math.min(length, packetSize); | ||||
|     length -= dataToTransmit; | ||||
| 
 | ||||
|     const chunk = data.slice(0, dataToTransmit); | ||||
|     data = data.slice(dataToTransmit); | ||||
|     await device.transferOut(1, chunk); | ||||
|     writeCount++; | ||||
|   } | ||||
| 
 | ||||
|   return writeCount; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function readFileAsArrayBuffer(file) { | ||||
|   return new Promise((res, rej) => { | ||||
|     const reader = new FileReader(); | ||||
|     reader.onload = e => { | ||||
|       res(e.target.result); | ||||
|     } | ||||
|     reader.readAsArrayBuffer(file); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| let device; | ||||
| 
 | ||||
| async function launchPayload(payload) { | ||||
|   await device.open(); | ||||
|   logOutput(`Connected to ${device.manufacturerName} ${device.productName}`); | ||||
| 
 | ||||
|   if (device.configuration === null) { | ||||
|     await device.selectConfiguration(1); | ||||
|   } | ||||
| 
 | ||||
|   await device.claimInterface(0); | ||||
| 
 | ||||
|   const deviceID = await device.transferIn(1, 16); | ||||
|   logOutput(`Device ID: ${bufferToHex(deviceID.data)}`); | ||||
| 
 | ||||
|   const rcmPayload = createRCMPayload(intermezzo, payload); | ||||
|   logOutput("Sending payload..."); | ||||
|   const writeCount = await write(device, rcmPayload); | ||||
|   logOutput("Payload sent!"); | ||||
| 
 | ||||
|   if (writeCount % 2 !== 1) { | ||||
|     logOutput("Switching to higher buffer..."); | ||||
|     await device.transferOut(1, new ArrayBuffer(0x1000)); | ||||
|   } | ||||
| 
 | ||||
|   logOutput("Trigging vulnerability..."); | ||||
|   const vulnerabilityLength = 0x7000; | ||||
|   const smash = await device.controlTransferIn({ | ||||
|     requestType: 'standard', | ||||
|     recipient: 'interface', | ||||
|     request: 0x00, | ||||
|     value: 0x00, | ||||
|     index: 0x00 | ||||
|   }, vulnerabilityLength); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| document.getElementById("goButton").addEventListener("click", async () => { | ||||
|   clearLog(); | ||||
|   var debugCheckbox = document.getElementById("shouldDebug"); | ||||
|   const payloadPath = document.getElementById("payloadSelect").value; | ||||
| 
 | ||||
|   if(!debugCheckbox.checked) { | ||||
| 
 | ||||
|   logOutput("Requesting access to device..."); | ||||
|   try { | ||||
|     device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x0955 }] }); | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     logOutput("Failed to get a device. Did you chose one?"); | ||||
|     return; | ||||
|   } | ||||
|   } | ||||
| 
 | ||||
|   let payload; | ||||
|   if (payloadPath === "uploaded") { | ||||
|     const file = document.getElementById("payloadUpload").files[0]; | ||||
|     if (!file) { | ||||
|       alert("You need to upload a file, to use an uploaded file."); | ||||
|       return; | ||||
|     } | ||||
|     logOutput("Using uploaded payload \"" + file.name + "\""); | ||||
|     payload = new Uint8Array(await readFileAsArrayBuffer(file)); | ||||
| 
 | ||||
|   } else { | ||||
|     try { | ||||
|       payload = new Uint8Array(await getPayload(payloadPath)); | ||||
|     } catch (error) { | ||||
|       logOutput("There was a problem retreiving the payload. Error: " + error) | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if(debugCheckbox.checked) { | ||||
|     logOutput("Logging payload bytes..."); | ||||
| 
 | ||||
|     var payloadToLog = ""; | ||||
|     for (var i = 0; i < payload.length; i++) { | ||||
|       payloadToLog += "0x" + payload[i].toString(16) + ", ".toUpperCase(); | ||||
|     } | ||||
|     payloadToLog = payloadToLog; | ||||
|     logOutput(payloadToLog); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   logOutput(`<span style='color:blue'>Preparing to launch ${payloadType}...</span>`); | ||||
|   launchPayload(payload); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function onSelectChange() { | ||||
|   if (document.getElementById("payloadSelect").value === "uploaded") | ||||
|     document.getElementById("uploadContainer").style.display = "block" | ||||
|   else | ||||
|     document.getElementById("uploadContainer").style.display = "none" | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function openInfo() { | ||||
|   if(document.getElementById("infodiv").innerHTML != "") { | ||||
|     document.getElementById("infodiv").innerHTML = ""; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function openInstructions() { | ||||
|   if(document.getElementById("infodiv").innerHTML != "") { | ||||
|     document.getElementById("infodiv").innerHTML = ""; | ||||
|   } | ||||
| } | ||||
| function logOutput(...message) { | ||||
|   document.getElementById("output").innerHTML = document.getElementById("output").innerHTML + message.join(" ") + "<br>"; | ||||
| } | ||||
| 
 | ||||
| function clearLog() { | ||||
|   document.getElementById("output").innerHTML = ""; | ||||
| } | ||||
| 
 | ||||
| async function getPayloadList(){ | ||||
|   return fetch("payloads/payloads.json") | ||||
|   .then((response) => { | ||||
|     if(!response.ok) | ||||
|       throw new Error(response.status); | ||||
|     return response.json(); | ||||
|   }) | ||||
|   .then((data) => { | ||||
|     return data.payloads; | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| (async () => { | ||||
|   const payloadSelect = document.getElementById("payloadSelect"); | ||||
|   let payloadList; | ||||
|   try { | ||||
|     payloadList = await getPayloadList(); | ||||
|      | ||||
|   } catch (error) { | ||||
|     logOutput("There was a problem retreiving the payload list. Error: " + error); | ||||
|     return; | ||||
|   } | ||||
|   payloadList.forEach((payload) => { | ||||
|     const payloadOption = document.createElement("option"); | ||||
| 
 | ||||
|     payloadOption.value = payload.path; | ||||
|     payloadOption.innerHTML = payload.name + " " + payload.version; | ||||
| 
 | ||||
|     payloadSelect.appendChild(payloadOption); | ||||
|   }); | ||||
| 
 | ||||
| })() | ||||
| 
 | ||||
| async function getPayload(payloadSrc){ | ||||
| 	return fetch(payloadSrc) | ||||
| 	.then((response) => { | ||||
| 		if(!response.ok) | ||||
| 			throw new Error(response.status); | ||||
| 		return response.arrayBuffer(); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| const intermezzo = new Uint8Array([ | ||||
|   0x44, 0x00, 0x9F, 0xE5, 0x01, 0x11, 0xA0, 0xE3, 0x40, 0x20, 0x9F, 0xE5, 0x00, 0x20, 0x42, 0xE0, | ||||
|   0x08, 0x00, 0x00, 0xEB, 0x01, 0x01, 0xA0, 0xE3, 0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0xA0, 0xE1, | ||||
|   0x2C, 0x00, 0x9F, 0xE5, 0x2C, 0x10, 0x9F, 0xE5, 0x02, 0x28, 0xA0, 0xE3, 0x01, 0x00, 0x00, 0xEB, | ||||
|   0x20, 0x00, 0x9F, 0xE5, 0x10, 0xFF, 0x2F, 0xE1, 0x04, 0x30, 0x90, 0xE4, 0x04, 0x30, 0x81, 0xE4, | ||||
|   0x04, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0x1A, 0x1E, 0xFF, 0x2F, 0xE1, 0x20, 0xF0, 0x01, 0x40, | ||||
|   0x5C, 0xF0, 0x01, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x01, 0x40 | ||||
| ]); | ||||
| 
 | ||||
| const RCM_PAYLOAD_ADDRESS = 0x40010000; | ||||
| const INTERMEZZO_LOCATION = 0x4001F000; | ||||
| const PAYLOAD_LOAD_BLOCK = 0x40020000; | ||||
| 
 | ||||
| function createRCMPayload(intermezzo, payload) { | ||||
|   const rcmLength = 0x30298; | ||||
| 
 | ||||
|   const intermezzoAddressRepeatCount = (INTERMEZZO_LOCATION - RCM_PAYLOAD_ADDRESS) / 4; | ||||
| 
 | ||||
|   const rcmPayloadSize = Math.ceil((0x2A8 + (0x4 * intermezzoAddressRepeatCount) + 0x1000 + payload.byteLength) / 0x1000) * 0x1000; | ||||
| 
 | ||||
|   const rcmPayload = new Uint8Array(new ArrayBuffer(rcmPayloadSize)) | ||||
|   const rcmPayloadView = new DataView(rcmPayload.buffer); | ||||
| 
 | ||||
|   rcmPayloadView.setUint32(0x0, rcmLength, true); | ||||
| 
 | ||||
|   for (let i = 0; i < intermezzoAddressRepeatCount; i++) { | ||||
|     rcmPayloadView.setUint32(0x2A8 + i * 4, INTERMEZZO_LOCATION, true); | ||||
|   } | ||||
| 
 | ||||
|   rcmPayload.set(intermezzo, 0x2A8 + (0x4 * intermezzoAddressRepeatCount)); | ||||
|   rcmPayload.set(payload, 0x2A8 + (0x4 * intermezzoAddressRepeatCount) + 0x1000); | ||||
| 
 | ||||
|   return rcmPayload; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function bufferToHex(data) { | ||||
|   let result = ""; | ||||
|   for (let i = 0; i < data.byteLength; i++) | ||||
|     result += data.getUint8(i).toString(16).padStart(2, "0"); | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| async function write(device, data) { | ||||
|   let length = data.length; | ||||
|   let writeCount = 0; | ||||
|   const packetSize = 0x1000; | ||||
| 
 | ||||
|   while (length) { | ||||
|     const dataToTransmit = Math.min(length, packetSize); | ||||
|     length -= dataToTransmit; | ||||
| 
 | ||||
|     const chunk = data.slice(0, dataToTransmit); | ||||
|     data = data.slice(dataToTransmit); | ||||
|     await device.transferOut(1, chunk); | ||||
|     writeCount++; | ||||
|   } | ||||
| 
 | ||||
|   return writeCount; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function readFileAsArrayBuffer(file) { | ||||
|   return new Promise((res, rej) => { | ||||
|     const reader = new FileReader(); | ||||
|     reader.onload = e => { | ||||
|       res(e.target.result); | ||||
|     } | ||||
|     reader.readAsArrayBuffer(file); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| let device; | ||||
| 
 | ||||
| async function launchPayload(payload) { | ||||
|   await device.open(); | ||||
|   logOutput(`Connected to ${device.manufacturerName} ${device.productName}`); | ||||
| 
 | ||||
|   if (device.configuration === null) { | ||||
|     await device.selectConfiguration(1); | ||||
|   } | ||||
| 
 | ||||
|   await device.claimInterface(0); | ||||
| 
 | ||||
|   const deviceID = await device.transferIn(1, 16); | ||||
|   logOutput(`Device ID: ${bufferToHex(deviceID.data)}`); | ||||
| 
 | ||||
|   const rcmPayload = createRCMPayload(intermezzo, payload); | ||||
|   logOutput("Sending payload..."); | ||||
|   const writeCount = await write(device, rcmPayload); | ||||
|   logOutput("Payload sent!"); | ||||
| 
 | ||||
|   if (writeCount % 2 !== 1) { | ||||
|     logOutput("Switching to higher buffer..."); | ||||
|     await device.transferOut(1, new ArrayBuffer(0x1000)); | ||||
|   } | ||||
| 
 | ||||
|   logOutput("Trigging vulnerability..."); | ||||
|   const vulnerabilityLength = 0x7000; | ||||
|   const smash = await device.controlTransferIn({ | ||||
|     requestType: 'standard', | ||||
|     recipient: 'interface', | ||||
|     request: 0x00, | ||||
|     value: 0x00, | ||||
|     index: 0x00 | ||||
|   }, vulnerabilityLength); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| document.getElementById("goButton").addEventListener("click", async () => { | ||||
|   clearLog(); | ||||
|   var debugCheckbox = document.getElementById("shouldDebug"); | ||||
|   const payloadPath = document.getElementById("payloadSelect").value; | ||||
| 
 | ||||
|   if(!debugCheckbox.checked) { | ||||
| 
 | ||||
|   logOutput("Requesting access to device..."); | ||||
|   try { | ||||
|     device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x0955 }] }); | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     logOutput("Failed to get a device. Did you chose one?"); | ||||
|     return; | ||||
|   } | ||||
|   } | ||||
| 
 | ||||
|   let payload; | ||||
|   if (payloadPath === "uploaded") { | ||||
|     const file = document.getElementById("payloadUpload").files[0]; | ||||
|     if (!file) { | ||||
|       alert("You need to upload a file, to use an uploaded file."); | ||||
|       return; | ||||
|     } | ||||
|     logOutput("Using uploaded payload \"" + file.name + "\""); | ||||
|     payload = new Uint8Array(await readFileAsArrayBuffer(file)); | ||||
| 
 | ||||
|   } else { | ||||
|     try { | ||||
|       payload = new Uint8Array(await getPayload(payloadPath)); | ||||
|     } catch (error) { | ||||
|       logOutput("There was a problem retreiving the payload. Error: " + error) | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if(debugCheckbox.checked) { | ||||
|     logOutput("Logging payload bytes..."); | ||||
| 
 | ||||
|     var payloadToLog = ""; | ||||
|     for (var i = 0; i < payload.length; i++) { | ||||
|       payloadToLog += "0x" + payload[i].toString(16) + ", ".toUpperCase(); | ||||
|     } | ||||
|     payloadToLog = payloadToLog; | ||||
|     logOutput(payloadToLog); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   logOutput(`<span style='color:blue'>Preparing to launch ${payloadPath}...</span>`); | ||||
|   launchPayload(payload); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function onSelectChange() { | ||||
|   if (document.getElementById("payloadSelect").value === "uploaded") | ||||
|     document.getElementById("uploadContainer").style.display = "block" | ||||
|   else | ||||
|     document.getElementById("uploadContainer").style.display = "none" | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function openInfo() { | ||||
|   if(document.getElementById("infodiv").innerHTML != "") { | ||||
|     document.getElementById("infodiv").innerHTML = ""; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function openInstructions() { | ||||
|   if(document.getElementById("infodiv").innerHTML != "") { | ||||
|     document.getElementById("infodiv").innerHTML = ""; | ||||
|   } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user