Page MenuHomeSealhub

No OneTemporary

diff --git a/http_server/code/index.html b/http_server/code/index.html
index e8053f7..0a73df8 100644
--- a/http_server/code/index.html
+++ b/http_server/code/index.html
@@ -1,186 +1,189 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Rentgen android</title>
<style>
main {
display: flex;
}
.log-section {
height: 600px;
width: 480px;
overflow-y: auto;
display: flex;
flex-direction: column;
margin-left: 20px;
}
.screen {
display: inline-block;
cursor: pointer;
}
.screen-buttons {
display: flex;
justify-content: space-around;
margin-top: 5px;
gap: 10px;
}
.screen-buttons button {
font-size: 1.1rem;
padding: 10px 20px;
width: 100%;
cursor: pointer;
background-color: transparent;
}
.screen-buttons button:hover {
background-color: aqua;
}
#clicks-log {
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console,
monospace;
}
</style>
</head>
<body>
<main>
<section class="screen-section">
<img
id="screen"
alt="android screen"
src=""
draggable="false"
class="screen"
/>
<div class="screen-buttons">
<button class="screen-buttons-home">home</button>
<button class="screen-buttons-back">back</button>
</div>
</section>
<p id="clicks-log" class="log-section"></p>
<p id="traffic-log" class="log-section"></p>
</main>
<script>
var screen = document.getElementById("screen");
var clicksLog = document.getElementById("clicks-log");
const homeButton = document.querySelector(".screen-buttons-home");
const backButton = document.querySelector(".screen-buttons-back");
let lastTouch = new Date().getTime();
const calculateElapsedTime = (last) => {
const currentTouch = new Date().getTime();
const elapsedTime = currentTouch - lastTouch;
const elapsedSec = Math.round(elapsedTime / 1000);
lastTouch = currentTouch;
return elapsedSec;
};
const waitToLog = (clickInfoText) => {
const clickInfo = document.createElement("span");
const waitInfo = document.createElement("span");
waitInfo.textContent = `await wait(${calculateElapsedTime(
lastTouch
)});`;
clicksLog.appendChild(waitInfo);
clickInfo.textContent = clickInfoText;
clicksLog.appendChild(clickInfo);
};
const registerClick = ({ path, logText, body }) => {
const clicksLog = document.getElementById("clicks-log");
const span = document.createElement("span");
waitToLog(logText);
fetch(path, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
...(body ? { body } : {}),
});
};
homeButton.addEventListener("click", () =>
registerClick({ path: "home", logText: "await homeButton();" })
);
backButton.addEventListener("click", () =>
registerClick({ path: "back", logText: "await backButton();" })
);
async function displayImage() {
try {
const response = await fetch("screen");
const blob = await response.blob();
screen.src = URL.createObjectURL(blob);
} catch (error) {
console.error("Error fetching image: ", error);
}
}
let isDragging = false;
let startDraggingPosX = 0;
let endDraggingPosX = 0;
let startDraggingPosY = 0;
let endDraggingPosY = 0;
+ const screenSize = [320, 640]
+
const handleDraggStart = (e) => {
e.preventDefault();
isDragging = true;
startDraggingPosX = e.offsetX;
startDraggingPosY = e.offsetY;
};
screen.addEventListener("mousedown", handleDraggStart);
document.addEventListener("mouseup", (e) => {
endDraggingPosX = e.offsetX;
endDraggingPosY = e.offsetY;
if (
- (isDragging && Math.abs(endDraggingPosY - startDraggingPosY) > 10) ||
- Math.abs(endDraggingPosX - startDraggingPosX) > 10
+ isDragging && (Math.abs(endDraggingPosY - startDraggingPosY) > 10 ||
+ Math.abs(endDraggingPosX - startDraggingPosX) > 10)
) {
registerClick({
path: "drag",
logText: `await drag({x:${startDraggingPosX},y:${startDraggingPosY}},{x:${e.offsetX},y:${e.offsetY}});`,
body: `startX=${startDraggingPosX}&startY=${startDraggingPosY}&endX=${e.offsetX}&endY=${e.offsetY}`,
});
- isDragging = false;
} else {
const phoneX = event.offsetX;
const phoneY = event.offsetY;
- registerClick({
- path: "touch",
- logText: `await click(${phoneX}, ${phoneY});`,
- body: `x=${phoneX}&y=${phoneY}`,
- });
+ if (phoneX <= screenSize[0] && phoneY <= screenSize[1])
+ registerClick({
+ path: "touch",
+ logText: `await click(${phoneX}, ${phoneY});`,
+ body: `x=${phoneX}&y=${phoneY}`,
+ });
}
+ isDragging = false;
});
async function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
async function screenshot_loop() {
var before;
while (true) {
before = performance.now();
await displayImage();
while (performance.now() - before < ___screenshotDelayMs___)
await sleep(50);
}
}
screenshot_loop();
</script>
<script src="/trafficLog.js"></script>
</body>
</html>
diff --git a/http_server/code/index.mjs b/http_server/code/index.mjs
index 639917f..b519ae3 100644
--- a/http_server/code/index.mjs
+++ b/http_server/code/index.mjs
@@ -1,143 +1,82 @@
import express from "express";
-import net from "net";
-import fs from "fs";
import { readFile } from "node:fs/promises";
+import { guardedScreenshot, socket_client, waitFullBoot } from "./screenshot.mjs";
const device_size_x = 320;
const device_size_y = 640;
const app = express();
app.use(express.urlencoded({ extended: false }));
-const socket_client = net.createConnection({ port: 3000, host: "android" });
-
-async function sleep(time) {
- return new Promise((resolve) => setTimeout(resolve, time));
-}
-
-let doneWrite = 0;
-let screenshotPromise = null;
-
-async function screenshot() {
- const time_start = Date.now();
- socket_client.write("screenshot");
- while (!doneWrite) {
- await sleep(15);
- if (Date.now() - time_start > 2000) {
- console.error("Screenshot timed out after 2s");
- break; // timeout
- }
- }
- doneWrite = 0;
- screenshotPromise = null;
-}
-
-async function guardedScreenshot() {
- console.log("Requesting a screenshot");
- if (!screenshotPromise) {
- console.log("no ongoing promise, starting a new one");
- screenshotPromise = screenshot();
- }
- return screenshotPromise;
-}
-
-async function waitFullBoot() {
- var start = performance.now();
- var counter = 0;
-
- //will timeout after 10 min
- while (performance.now() - start < 600 * 1000) {
- var before = performance.now();
- await screenshot();
- var after = performance.now();
- if (after - before < process.env.screenshotDelayMs) counter++;
- else counter = 0;
-
- if (counter === 10) return;
- }
-
- throw new Error("wait for screenshot time to be less than 0.5s timed out");
-}
-
-let fd;
-socket_client.on("data", (dataBuf) => {
- if (dataBuf.toString() === "start")
- fd = fs.openSync("/code/screenshot.png", "w");
- else {
- if (dataBuf.toString().includes("ENDOFMSG")) {
- fs.writeSync(fd, dataBuf);
- fs.close(fd);
- doneWrite = 1;
- } else fs.writeSync(fd, dataBuf);
- }
-});
console.log("Waiting for full boot...");
await waitFullBoot();
console.log("Boot detected! activating endpoints");
-app.get("/screen", async function (req, res) {
- await guardedScreenshot();
- res.sendFile("/code/screenshot.png");
-});
-
+//GET
app.get("/favicon.ico", function (req, res) {
res.sendFile("/code/favicon.ico");
});
app.get("/trafficLog.js", function (req, res) {
res.sendFile("/code/dist/trafficLog.js");
});
app.get("/trafficLog", async function (req, res) {
res.sendFile("/log/trafficLog");
});
-app.post("/touch", function (req, res) {
- const x = parseInt(req.body.x);
- const y = parseInt(req.body.y);
-
- if (isNaN(x) || isNaN(y) || x > device_size_x || y > device_size_y) {
- res.send(
- `the query params must be x <= ${device_size_x}, y <= ${device_size_y}\n`
- );
- } else {
- socket_client.write(`touch ${x} ${y}`);
- res.sendStatus(200);
- }
+app.get("/screen", async function (req, res) {
+ await guardedScreenshot();
+ res.sendFile("/code/screenshot.png");
});
app.get("/", async function (req, res) {
let fileData = (await readFile("/code/index.html")).toString();
fileData = fileData.replace(
"___screenshotDelayMs___",
process.env.screenshotDelayMs
);
-
+
res.setHeader("Content-Type", "text/html");
res.setHeader("Content-Disposition", "inline");
-
+
res.send(fileData);
});
+//POST
app.post("/back", function (req, res) {
socket_client.write(`back`);
res.sendStatus(200);
});
app.post("/home", function (req, res) {
socket_client.write(`home`);
res.sendStatus(200);
});
+app.post("/touch", function (req, res) {
+ const x = parseInt(req.body.x);
+ const y = parseInt(req.body.y);
+
+ if (isNaN(x) || isNaN(y) || x > device_size_x || y > device_size_y) {
+ res.send(
+ `the query params must be x <= ${device_size_x}, y <= ${device_size_y}\n`
+ );
+ } else {
+ socket_client.write(`touch ${x} ${y}`);
+ res.sendStatus(200);
+ }
+});
+
app.post("/drag", function (req, res) {
const body = req.body;
const startX = Number(body.startX);
const startY = Number(body.startY);
const endX = Number(body.endX);
const endY = Number(body.endY);
socket_client.write(`drag ${startX} ${startY} ${endX} ${endY}`);
res.sendStatus(200);
});
app.listen(8080, () => console.log("Listening in port 8080"));
diff --git a/http_server/code/screenshot.mjs b/http_server/code/screenshot.mjs
new file mode 100644
index 0000000..9c93e15
--- /dev/null
+++ b/http_server/code/screenshot.mjs
@@ -0,0 +1,62 @@
+import net from "net";
+import fs from "fs";
+import { sleep } from "./utils.mjs";
+
+export const socket_client = net.createConnection({ port: 3000, host: "android" });
+
+let doneWrite = 0;
+let screenshotPromise = null;
+
+async function screenshot() {
+ const time_start = Date.now();
+ socket_client.write("screenshot");
+ while (!doneWrite) {
+ await sleep(15);
+ if (Date.now() - time_start > 2000) {
+ console.error("Screenshot timed out after 2s");
+ break; // timeout
+ }
+ }
+ doneWrite = 0;
+ screenshotPromise = null;
+}
+
+export async function guardedScreenshot() {
+ console.log("Requesting a screenshot");
+ if (!screenshotPromise) {
+ console.log("no ongoing promise, starting a new one");
+ screenshotPromise = screenshot();
+ }
+ return screenshotPromise;
+}
+
+export async function waitFullBoot() {
+ var start = performance.now();
+ var counter = 0;
+
+ //will timeout after 10 min
+ while (performance.now() - start < 600 * 1000) {
+ var before = performance.now();
+ await screenshot();
+ var after = performance.now();
+ if (after - before < process.env.screenshotDelayMs) counter++;
+ else counter = 0;
+
+ if (counter === 10) return;
+ }
+
+ throw new Error("wait for screenshot time to be less than 0.5s timed out");
+}
+
+let fd;
+socket_client.on("data", (dataBuf) => {
+ if (dataBuf.toString() === "start")
+ fd = fs.openSync("/code/screenshot.png", "w");
+ else {
+ if (dataBuf.toString().includes("ENDOFMSG")) {
+ fs.writeSync(fd, dataBuf);
+ fs.close(fd);
+ doneWrite = 1;
+ } else fs.writeSync(fd, dataBuf);
+ }
+});
\ No newline at end of file
diff --git a/http_server/code/utils.mjs b/http_server/code/utils.mjs
new file mode 100644
index 0000000..31e4abf
--- /dev/null
+++ b/http_server/code/utils.mjs
@@ -0,0 +1,3 @@
+export async function sleep(time) {
+ return new Promise((resolve) => setTimeout(resolve, time));
+}
\ No newline at end of file
diff --git a/intraContainerCom.txt b/intraContainerCom.txt
new file mode 100644
index 0000000..67d9d2d
--- /dev/null
+++ b/intraContainerCom.txt
@@ -0,0 +1,11 @@
+INTRA CONTAINER COMMUNICATION
+
+FROM HTTPSERVER TO ANDROID
+- screenshot
+- home
+- back
+- touch $x $y
+- drag $startx $starty $endx $endy
+
+FROM ANDROID TO HTTPSERVER
+- start $screenshotdata ENDOFMSG (to send screenshot data)
\ No newline at end of file
diff --git a/start.mjs b/start.mjs
index 12bc017..08d92b4 100644
--- a/start.mjs
+++ b/start.mjs
@@ -1,94 +1,94 @@
import { promises as fs } from "fs";
async function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
async function checkCertExistance() {
return await Promise.all([
fs.access("./certificates/mitmproxy-ca-cert.cer", fs.constants.R_OK),
fs.access("./certificates/mitmproxy-ca-cert.p12", fs.constants.R_OK),
fs.access("./certificates/mitmproxy-ca-cert.pem", fs.constants.R_OK),
fs.access("./certificates/mitmproxy-ca.p12"),
fs.access("./certificates/mitmproxy-ca.pem"),
fs.access("./certificates/mitmproxy-dhparam.pem", fs.constants.R_OK),
]);
}
async function generateCert() {
//remove certs if they exist
try {
await $`rm -rf certificates`;
} catch {
throw new Error(
"To remove certificates, and create new ones, this command must be run with sudo"
);
}
//iniciate docker which will create certs
$`docker run --rm -v $PWD/certificates:/home/mitmproxy/.mitmproxy --name certGenerator mitmproxy/mitmproxy:9.0.1 mitmdump &`;
//wait for certs to generate
let generated = false;
while (!generated) {
try {
await checkCertExistance();
generated = true;
} catch {}
}
//kill docker container
$`docker stop certGenerator`;
}
async function generatePreAndroid() {
await $`docker build -t pre_android pre_android`;
- $`docker run --rm -v $PWD/certificates/mitmproxy-ca-cert.cer:/ca-cert.cer -v $PWD/pre_android/preconf:/preconf --device=/dev/kvm --name pre_android_cont pre_android &`;
+ $`docker run --sysctl net.ipv6.conf.all.disable_ipv6=1 --rm -v $PWD/certificates/mitmproxy-ca-cert.cer:/ca-cert.cer -v $PWD/pre_android/preconf:/preconf --device=/dev/kvm --name pre_android_cont pre_android &`;
console.log(
"Installing tls certificate and culebra into the android pre-image..."
);
//the way of knowing when the culebra install is creating a file in the shared volume
let finished = false;
while (!finished) {
try {
await fs.access(
"./pre_android/preconf/finished",
fs.constants.R_OK
),
$`rm -f ./pre_android/preconf/finished`;
finished = true;
} catch {
await sleep(100);
}
}
await $`docker commit pre_android_cont pre_android/ready`;
$`docker stop pre_android_cont`;
}
if (process.argv.length !== 4) throw new Error("expected an argument");
else if (process.argv[3] === "up") {
try {
await checkCertExistance();
} catch {
await generateCert();
}
try {
await $`docker image inspect pre_android/ready > /dev/null 2> /dev/null`;
} catch {
await generatePreAndroid();
}
await $`docker compose build`;
await $`docker compose up`;
} else if (process.argv[3] === "down") await $`docker compose down`;
else if (process.argv[3] === "generateCert") {
generateCert();
} else if (process.argv[3] === "generatePreAndroid") {
generatePreAndroid();
} else
throw new Error(
- "expected [up | down | generateCert | generatePreAndroid ] as argument"
+ "expected [ up | down | generateCert | generatePreAndroid ] as argument"
);

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 8, 05:47 (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1034069
Default Alt Text
(16 KB)

Event Timeline