Skip to content

Commit

Permalink
Merge pull request #14 from PipeItToDevNull/1-integrate-debug_dumps
Browse files Browse the repository at this point in the history
1 integrate debug dumps
  • Loading branch information
PipeItToDevNull authored Nov 12, 2024
2 parents 42203a4 + c0204ee commit 1a0e43c
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 105 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "api/Debug-Dmps"]
path = api/Debug-Dmps
url = https://github.com/PipeItToDevNull/Debug-Dmps.git
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ A basic API to injest `.dmp` files and return analyzed text.
- The base container for the API
- Windows Core 2022 image containing Windows SDK with only Debugging Tools installed.

## API Usage
## API
### Usage
With a file
```bash
curl.exe -X PUT http://localhost:3000/analyze-dmp -F "dmpFile=@path/to/test.dmp"
Expand All @@ -19,8 +20,8 @@ With a URL
```bash
curl -X PUT http://localhost:3000/analyze-dmp -F "url=http://example.com/file.dmp"
```

## Azure deployment method
## SWA
### Azure deployment method
```bash
az group create --name <your-resource-group> --location eastus2
az deployment group create --resource-group <your-resource-group> --template-file template.json
Expand Down
1 change: 1 addition & 0 deletions api/Debug-Dmps
Submodule Debug-Dmps added at aea0ef
2 changes: 1 addition & 1 deletion api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ FROM ghcr.io/pipeittodevnull/windebug-container:latest
RUN powershell -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"

# Install Node.js using Chocolatey
RUN choco install nodejs-lts -y
RUN choco install nodejs-lts pwsh -y

# Set the working directory
WORKDIR C:\\app
Expand Down
12 changes: 9 additions & 3 deletions api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ app.use((req, res, next) => {
// Function to analyze the file using a command-line debugger
const analyzeFile = (filePath, res) => {
logger.info(`Analyzing file: ${filePath}`);
exec(`cdb.exe -z ${filePath} -c "k; !analyze -v; q"`, (error, stdout, stderr) => {
exec(`pwsh -File C:\\App\\Debug-Dmps\\Debug-Dmps.ps1 -Target ${filePath}`, (error, stdout, stderr) => {
// Delete the file after processing
fs.unlink(filePath, (err) => {
if (err) {
Expand All @@ -105,8 +105,14 @@ const analyzeFile = (filePath, res) => {
res.status(500).send(`An error occurred while analyzing the file`);
return;
}
logger.info('Analysis output sent to client');
res.send(`Output: ${stdout}`);
try {
const jsonOutput = JSON.parse(stdout);
logger.info('Analysis output sent to client');
res.json(jsonOutput);
} catch (parseError) {
logger.error(`Failed to parse JSON output: ${parseError.message}`);
res.status(500).send({ error: 'Failed to parse JSON output' });
}
});
};

Expand Down
273 changes: 175 additions & 98 deletions swa/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,113 +7,190 @@ const SITE_NAME = process.env.REACT_APP_SITE_NAME;
const API_URL = `${process.env.REACT_APP_API_URL}/analyze-dmp`;

const FileUpload = () => {
const [file, setFile] = useState(null);
const [url, setUrl] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const [responseData, setResponseData] = useState('');

const handleFileChange = (e) => {
setFile(e.target.files[0]);
};

const handleUrlChange = (e) => {
setUrl(e.target.value);
};

const handleFileUpload = async () => {
if (!file) return;

const formData = new FormData();
formData.append('dmpFile', file);

setLoading(true);
setError('');
setResponseData('');

try {
const response = await fetch(API_URL, {
method: 'PUT',
body: formData,
});

if (!response.ok) {
throw new Error('Network response was not ok');
}

const data = await response.text();
setResponseData(data);
} catch (error) {
console.error('Error uploading file:', error);
setError('Error uploading file');
} finally {
setLoading(false);
}
};

const handleUrlSubmit = async () => {
if (!url) return;

setLoading(true);
setError('');
setResponseData('');

try {
const response = await fetch(`${API_URL}?url=${encodeURIComponent(url)}`, {
method: 'PUT',
});

if (!response.ok) {
throw new Error('Network response was not ok');
}

const data = await response.text();
setResponseData(data);
} catch (error) {
console.error('Error submitting URL:', error);
setError('Error submitting URL');
} finally {
setLoading(false);
}
};

return (
<div>
const [file, setFile] = useState(null);
const [url, setUrl] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const [responseData, setResponseData] = useState('');

const handleFileChange = (e) => {
setFile(e.target.files[0]);
};

const handleUrlChange = (e) => {
setUrl(e.target.value);
};

const handleFileUpload = async () => {
if (!file) return;

const formData = new FormData();
formData.append('dmpFile', file);

setLoading(true);
setError('');
setResponseData('');

try {
const response = await fetch(API_URL, {
method: 'PUT',
body: formData,
});

if (!response.ok) {
throw new Error('Network response was not ok');
}

const data = await response.text();
setResponseData(data);
} catch (error) {
console.error('Error uploading file:', error);
setError('Error uploading file');
} finally {
setLoading(false);
}
};

const handleUrlSubmit = async () => {
if (!url) return;

setLoading(true);
setError('');
setResponseData('');

try {
const response = await fetch(`${API_URL}?url=${encodeURIComponent(url)}`, {
method: 'PUT',
});

if (!response.ok) {
throw new Error('Network response was not ok');
}

const data = await response.text();
setResponseData(data);
} catch (error) {
console.error('Error submitting URL:', error);
setError('Error submitting URL');
} finally {
setLoading(false);
}
};

// Function to validate JSON Response
const isValidJson = (data) => {
try {
JSON.parse(data);
return true;
} catch (e) {
return false;
}
};

// Function to sort JSON keys
const sortJson = (data, order) => {
return order.reduce((acc, key) => {
if (data.hasOwnProperty(key)) {
acc[key] = data[key];
}
return acc;
}, {});
};

// Function to render JSON object into HTML objects
const renderJsonToHtml = (data) => {
console.log("Data received:", data); // Debugging line

// No clue what this does, but everything is rendered inside it
if (Array.isArray(data)) {
return data.map((item, index) => (
<>
{renderJsonToHtml(item)}
</>
));
}

// Define the key order to display in
const order = [
"dmpInfo",
"analysis",
"rawContent",
];
const specialKeys = ["rawContent"];
const sortedData = sortJson(data, order);

// Convert object to array of key-value pairs
const keyValueArray = Object.entries(sortedData).map(([key, value]) => ({ key, value }));

// Separate the special items
const specialItems = keyValueArray.filter(item => specialKeys.includes(item.key));
const regularItems = keyValueArray.filter(item => !specialKeys.includes(item.key));

// Render the regular items
const regularRender = regularItems.map((item, index) => (
<>
<h2 class={`${item.key} result-header`}>
{item.key}
</h2>
<div class="result-content">
{item.value}
</div>
</>
));

// Render the special items with their own method
const specialRender = specialItems.map((item, index) => (
<div key={index} className={item.key}>
<details>
<summary>Raw results</summary>
<div class="result-content">{item.value}</div>
</details>
</div>
));

// Combine both renders
return (
<>
{regularRender}
{specialRender}
</>
);
};

return (
<div>
<Helmet>
<title>{SITE_NAME}</title>
<title>{SITE_NAME}</title>
</Helmet>
<div id="container">
<div id="header">
<h1 id="site_name">{SITE_NAME}</h1>
</div>
<div class="button-container">
<div class="button-div">
<input type="file" onChange={handleFileChange} />
<button onClick={handleFileUpload} disabled={loading}>
{loading ? 'Uploading...' : 'Upload File'}
</button>
<div id="container">
<div id="header">
<h1 id="site_name">{SITE_NAME}</h1>
</div>
<div class="button-div">
<input type="text" value={url} onChange={handleUrlChange} placeholder="Enter URL" />
<button onClick={handleUrlSubmit} disabled={loading}>
{loading ? 'Submitting...' : 'Upload URL'}
</button>
<div class="button-container">
<div class="button-div">
<input type="file" onChange={handleFileChange} />
<button onClick={handleFileUpload} disabled={loading}>
{loading ? 'Uploading...' : 'Upload File'}
</button>
</div>
<div class="button-div">
<input type="text" value={url} onChange={handleUrlChange} placeholder="Enter URL" />
<button onClick={handleUrlSubmit} disabled={loading}>
{loading ? 'Submitting...' : 'Upload URL'}
</button>
</div>
</div>
</div>

<div id="content">
{!error && !responseData && <p>Upload your .dmp file or provide a download link above</p>}
<div id="content">
{!error && !responseData && <p>{loading ? 'Processing...' : 'Upload your .dmp file or provide a download link above'}</p>}
{error && <p style={{ color: 'red' }}>{error}</p>}
{responseData && (
<div id="content">
<pre>{responseData}</pre> {/* Display the plain text response */}
</div>
<>{renderJsonToHtml(JSON.parse(responseData))}</>
)}
</div>
</div>
<Footer />
</div>
</div>
</div>
);
);
};

export default FileUpload;
Loading

0 comments on commit 1a0e43c

Please sign in to comment.