mirror of
https://github.com/radareorg/r2wars.git
synced 2026-11-09 12:41:30 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16f21b44ae | ||
|
|
2121fed687 | ||
|
|
cef1c7a097 | ||
|
|
84dd048b84 | ||
|
|
672df06cf4 | ||
|
|
508db1c2bc | ||
|
|
097f9405f6 | ||
|
|
915869ddd4 | ||
|
|
120a0c2502 | ||
|
|
30558ea731 | ||
|
|
c97fd325f2 | ||
|
|
14a092e536 | ||
|
|
85d4ec3b49 | ||
|
|
756700f93b | ||
|
|
9313756380 | ||
|
|
80ea942513 | ||
|
|
1002399ce9 | ||
|
|
f493c3706d | ||
|
|
29e37fe36d | ||
|
|
3828a549c2 | ||
|
|
36b0f07c0c | ||
|
|
1834ea4f11 | ||
|
|
347bba1441 | ||
|
|
4b55638d2c | ||
|
|
5936113029 | ||
|
|
86854d490d | ||
|
|
7820cc36e2 | ||
|
|
d4d4c595da | ||
|
|
91686018a2 | ||
|
|
02430027f8 | ||
|
|
9be5d63861 | ||
|
|
6777a5134e | ||
|
|
6317137aaa | ||
|
|
0d5458bdd1 | ||
|
|
c445b3b145 | ||
|
|
feb51c621d | ||
|
|
7cd63a3210 | ||
|
|
0c5affe865 | ||
|
|
63166db01a | ||
|
|
65df30022c | ||
|
|
a6125a22f5 | ||
|
|
5cbd827822 | ||
|
|
23e506cd65 | ||
|
|
0aa7a5e617 | ||
|
|
5e683c2794 | ||
|
|
c9c4702b37 | ||
|
|
a454e45679 | ||
|
|
3dd1ae6257 | ||
|
|
4236326c89 | ||
|
|
03e0f6fc77 | ||
|
|
448c0f014b | ||
|
|
41f866157a | ||
|
|
dd14ab1d7f | ||
|
|
e7f532be89 | ||
|
|
fa3804da2f | ||
|
|
b442cec725 | ||
|
|
d9f548d0e6 | ||
|
|
0e514bee77 | ||
|
|
5ae6291f89 | ||
|
|
b99220cfd7 | ||
|
|
efb9dbe8cf | ||
|
|
2d3639a2df | ||
|
|
9381ccfb8a | ||
|
|
15905b2860 | ||
|
|
056c9faf71 | ||
|
|
0d97537739 | ||
|
|
aeab41de68 | ||
|
|
4715c10c06 | ||
|
|
6a9dd887f9 | ||
|
|
080d80f73d | ||
|
|
fcadb178f3 | ||
|
|
267d855063 | ||
|
|
186ef4d158 | ||
|
|
4d818caca7 | ||
|
|
149217dc75 | ||
|
|
b878b99a6d | ||
|
|
d8a265cbef | ||
|
|
06dc00704c | ||
|
|
14e48452b5 |
No files matched your search
@@ -0,0 +1,4 @@
|
||||
# Ignore everything...
|
||||
*
|
||||
# ...apart from the csharp subdirectory which is the only one that's needed
|
||||
!csharp/
|
||||
@@ -0,0 +1,11 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "##build "
|
||||
prefix-development: "##build "
|
||||
labels:
|
||||
- buildsystem
|
||||
@@ -0,0 +1,100 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
is_release: ${{ steps.release.outputs.is_release }}
|
||||
tag_name: ${{ steps.release.outputs.tag_name }}
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Build Docker image
|
||||
run: make build
|
||||
|
||||
- name: Check for a release tag
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
id: release
|
||||
shell: bash
|
||||
run: |
|
||||
tag="$(git describe --exact-match --tags "$GITHUB_SHA" 2>/dev/null || true)"
|
||||
if [[ "$tag" =~ ^[0-9] ]]; then
|
||||
echo "is_release=yes" >> "$GITHUB_OUTPUT"
|
||||
echo "tag_name=$tag" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "is_release=no" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Check release version
|
||||
if: ${{ steps.release.outputs.is_release == 'yes' }}
|
||||
env:
|
||||
TAG_NAME: ${{ steps.release.outputs.tag_name }}
|
||||
run: |
|
||||
version=$(./version.sh)
|
||||
if [ "$TAG_NAME" != "$version" ]; then
|
||||
echo "Tag $TAG_NAME does not match version $version" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create distribution archive
|
||||
if: ${{ steps.release.outputs.is_release == 'yes' }}
|
||||
env:
|
||||
TAG_NAME: ${{ steps.release.outputs.tag_name }}
|
||||
run: |
|
||||
archive="r2wars-$TAG_NAME"
|
||||
container=$(docker create r2wars:latest)
|
||||
trap 'docker rm -f "$container" >/dev/null' EXIT
|
||||
|
||||
docker cp "$container:/r2wars/." release-bin
|
||||
mkdir "$archive"
|
||||
cp -R release-bin/. "$archive/"
|
||||
cp -R examples "$archive/warriors"
|
||||
cp RELEASE_README.md "$archive/README.txt"
|
||||
zip -r "$archive.zip" "$archive"
|
||||
|
||||
- name: Store distribution archive
|
||||
if: ${{ steps.release.outputs.is_release == 'yes' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: r2wars-${{ steps.release.outputs.tag_name }}
|
||||
path: r2wars-${{ steps.release.outputs.tag_name }}.zip
|
||||
if-no-files-found: error
|
||||
|
||||
release:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && needs.build.outputs.is_release == 'yes' }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Download distribution archive
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: r2wars-${{ needs.build.outputs.tag_name }}
|
||||
path: release
|
||||
|
||||
- name: Publish GitHub release
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
TAG_NAME: ${{ needs.build.outputs.tag_name }}
|
||||
run: |
|
||||
archive="release/r2wars-$TAG_NAME.zip"
|
||||
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
|
||||
gh release upload "$TAG_NAME" "$archive" --clobber
|
||||
else
|
||||
gh release create "$TAG_NAME" "$archive" --verify-tag --generate-notes
|
||||
fi
|
||||
@@ -0,0 +1,39 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: "1 4 * * 4"
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ javascript, csharp ]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: none
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
@@ -0,0 +1,43 @@
|
||||
name: WebAssembly
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/workflows/wasm.yml"
|
||||
- "csharp/wwwroot/**"
|
||||
- "wasm/**"
|
||||
- "Makefile"
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/wasm.yml"
|
||||
- "csharp/wwwroot/**"
|
||||
- "wasm/**"
|
||||
- "Makefile"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-and-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
cache-dependency-path: wasm/package-lock.json
|
||||
- run: npm ci
|
||||
working-directory: wasm
|
||||
- run: npm test
|
||||
working-directory: wasm
|
||||
- run: npm run build
|
||||
working-directory: wasm
|
||||
- name: Check shared .NET client bundle
|
||||
run: git diff --exit-code -- csharp/wwwroot/assets/r2wars-ui.js
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: r2wars-wasm
|
||||
path: wasm/dist
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,2 @@
|
||||
csharp/bin/
|
||||
csharp/obj/
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
||||
@@ -1,76 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Nancy;
|
||||
using Nancy.Bootstrapper;
|
||||
using Nancy.Responses;
|
||||
using Nancy.Session;
|
||||
using Nancy.ViewEngines;
|
||||
using Nancy.TinyIoc;
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
public class CustomBootstrapper : DefaultNancyBootstrapper
|
||||
{
|
||||
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
|
||||
{
|
||||
base.ConfigureApplicationContainer(container);
|
||||
ResourceViewLocationProvider.RootNamespaces.Add(Assembly.GetAssembly(typeof(MainModule)), "r2warsTorneo.Views");
|
||||
}
|
||||
|
||||
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
|
||||
{
|
||||
base.ApplicationStartup(container, pipelines);
|
||||
CookieBasedSessions.Enable(pipelines);
|
||||
}
|
||||
|
||||
/*protected override void ConfigureConventions(NancyConventions conventions)
|
||||
{
|
||||
base.ConfigureConventions(conventions);
|
||||
conventions.StaticContentsConventions.Add(AddStaticResourcePath("/content", Assembly.GetAssembly(typeof(MainModule)), "r2wars.Web.Views.content"));
|
||||
}*/
|
||||
|
||||
protected override NancyInternalConfiguration InternalConfiguration
|
||||
{
|
||||
get
|
||||
{
|
||||
return NancyInternalConfiguration.WithOverrides(OnConfigurationBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
void OnConfigurationBuilder(NancyInternalConfiguration x)
|
||||
{
|
||||
x.ViewLocationProvider = typeof(ResourceViewLocationProvider);
|
||||
}
|
||||
protected override byte[] FavIcon
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
public static Func<NancyContext, string, Response> AddStaticResourcePath(string requestedPath, Assembly assembly, string namespacePrefix)
|
||||
{
|
||||
return (context, s) =>
|
||||
{
|
||||
var path = context.Request.Path;
|
||||
if (!path.StartsWith(requestedPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string resourcePath;
|
||||
string name;
|
||||
|
||||
var adjustedPath = path.Substring(requestedPath.Length + 1);
|
||||
if (adjustedPath.IndexOf('/') >= 0)
|
||||
{
|
||||
name = Path.GetFileName(adjustedPath);
|
||||
resourcePath = namespacePrefix + "." + adjustedPath.Substring(0, adjustedPath.Length - name.Length - 1).Replace('/', '.');
|
||||
}
|
||||
else
|
||||
{
|
||||
name = adjustedPath;
|
||||
resourcePath = namespacePrefix;
|
||||
}
|
||||
return new EmbeddedFileResponse(assembly, resourcePath, name);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
ARG UBUNTU_RELEASE="24.04"
|
||||
ARG TIMEZONE="UTC"
|
||||
ARG DOTNET_IMAGE="10.0-noble"
|
||||
ARG R2_VERSION="6.2.0"
|
||||
|
||||
|
||||
################################################################################
|
||||
# Download the pinned radare2 release package #
|
||||
################################################################################
|
||||
FROM ubuntu:${UBUNTU_RELEASE} AS r2-package
|
||||
ARG R2_VERSION
|
||||
ARG TARGETARCH
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl
|
||||
|
||||
RUN case "${TARGETARCH}" in \
|
||||
amd64) R2_SHA256="eb82324e83315887fbee6f5d8632c982c593e056a87180f1bec5ccb06c463aeb" ;; \
|
||||
arm64) R2_SHA256="e866525e9874588d478d536cca38cf9a7562896725efb4119b886101fd93f1ec" ;; \
|
||||
*) echo "Unsupported Docker architecture: ${TARGETARCH}" >&2; exit 1 ;; \
|
||||
esac && \
|
||||
curl --fail --location --show-error \
|
||||
"https://github.com/radareorg/radare2/releases/download/${R2_VERSION}/radare2_${R2_VERSION}_${TARGETARCH}.deb" \
|
||||
--output /radare2.deb && \
|
||||
echo "${R2_SHA256} /radare2.deb" | sha256sum --check --strict
|
||||
|
||||
|
||||
################################################################################
|
||||
# r2wars builder #
|
||||
################################################################################
|
||||
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_IMAGE} AS r2wars-builder
|
||||
|
||||
COPY --link csharp /r2wars
|
||||
|
||||
WORKDIR /r2wars
|
||||
RUN dotnet publish r2wars.csproj \
|
||||
--configuration Release \
|
||||
--output /r2wars-publish \
|
||||
--no-self-contained
|
||||
|
||||
|
||||
################################################################################
|
||||
# r2wars runner #
|
||||
################################################################################
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:${DOTNET_IMAGE} AS runner
|
||||
ARG TIMEZONE
|
||||
|
||||
ENV TZ=${TIMEZONE}
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
--mount=type=bind,from=r2-package,source=/radare2.deb,target=/tmp/radare2.deb \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends /tmp/radare2.deb
|
||||
|
||||
COPY --from=r2wars-builder --link /r2wars-publish /r2wars
|
||||
|
||||
EXPOSE 9664 9966
|
||||
|
||||
WORKDIR /r2wars
|
||||
ENTRYPOINT ["dotnet", "r2wars.dll"]
|
||||
@@ -1,40 +0,0 @@
|
||||
using Nancy;
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
public class MainModule : NancyModule
|
||||
{
|
||||
public MainModule()
|
||||
{
|
||||
Get["/"] = x => View["index.html"];
|
||||
}
|
||||
}
|
||||
/*public class r2warsModule : NancyModule
|
||||
{
|
||||
public r2warsModule() : base("/r2wars")
|
||||
{
|
||||
Get["/refresh"] = x =>
|
||||
{
|
||||
//return r2wars.Codigo.r2wars.json_output();
|
||||
return "";
|
||||
};
|
||||
Get["/next"] = x =>
|
||||
{
|
||||
//r2wars.Codigo.r2wars.btStep_Click();
|
||||
//return r2wars.Codigo.r2wars.json_output();
|
||||
return "";
|
||||
};
|
||||
Get["/start"] = x =>
|
||||
{
|
||||
//r2wars.Codigo.r2wars.btAuto_Click();
|
||||
//return "";
|
||||
return "";
|
||||
};
|
||||
Get["/reset"] = x =>
|
||||
{
|
||||
//r2wars.Codigo.r2wars.btInit_Click();
|
||||
//return r2wars.Codigo.r2wars.json_output();
|
||||
return "";
|
||||
};
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -1,20 +1,38 @@
|
||||
VERSION=$(shell git tag|tail -n1)
|
||||
R2W=r2wars-$(VERSION)
|
||||
DOCKER ?= docker
|
||||
WASM_ARCHIVE ?= r2wars-wasm.zip
|
||||
|
||||
all:
|
||||
xbuild
|
||||
.PHONY: default build start stop clean wasm-build wasm-test wasm-run wasm-dist
|
||||
|
||||
dist:
|
||||
xbuild /p:Configuration=Release
|
||||
rm -rf $(R2W)
|
||||
mkdir -p $(R2W)
|
||||
cp -rf examples bin/Release/*.exe bin/Release/*.dll $(R2W)
|
||||
cp -f RELEASE_README.md $(R2W)/README.txt
|
||||
zip -r $(R2W).zip $(R2W)
|
||||
rm -rf $(R2W)
|
||||
default: start ## By default, just start the container
|
||||
|
||||
r2w32:
|
||||
wget -c http://radare.mikelloc.com/get/2.7.0/radare2_installer-msvc_64-2.7.0.exe
|
||||
build: ## Build the Docker image
|
||||
@$(DOCKER) compose build
|
||||
|
||||
clean:
|
||||
rm -rf bin obj r2wars r2wars.zip
|
||||
start: ## Start the container via docker compose (docker compose builds automatically if necessary)
|
||||
@$(DOCKER) compose up -d
|
||||
|
||||
run:
|
||||
$(MAKE) start
|
||||
sleep 2
|
||||
open http://127.0.0.1:9664/
|
||||
|
||||
stop: ## Tear down the container via docker compose
|
||||
@$(DOCKER) compose down
|
||||
|
||||
clean: stop ## Remove the project containers and docker image
|
||||
@if $(DOCKER) image inspect r2wars:latest >/dev/null 2>&1; then \
|
||||
$(DOCKER) image rm r2wars:latest; \
|
||||
fi
|
||||
|
||||
wasm-build: ## Build the standalone browser/WebAssembly version
|
||||
cd wasm && npm install && npm run build
|
||||
|
||||
wasm-test: ## Test the browser engine against radare2 WebAssembly
|
||||
cd wasm && npm install && npm test
|
||||
|
||||
wasm-run: ## Run the standalone browser/WebAssembly development server
|
||||
cd wasm && npm install && npm run dev
|
||||
|
||||
wasm-dist: wasm-build ## Build a static-host-ready WebAssembly zip archive
|
||||
cd wasm/dist && zip -qrFS "../$(WASM_ARCHIVE)" .
|
||||
@echo "Created wasm/$(WASM_ARCHIVE)"
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using WebSocketSharp.Server;
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
static public class r2warsStatic
|
||||
{
|
||||
static public r2wars r2w = new r2wars();
|
||||
static public Torneo torneo = new Torneo();
|
||||
}
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
string httpUrl = "http://localhost:9664";
|
||||
string websocketUrl = "ws://localhost:9966";
|
||||
var tokenSource = new CancellationTokenSource();
|
||||
CancellationToken ct = tokenSource.Token;
|
||||
if (args.Length > 0) {
|
||||
r2warsStatic.torneo.SetWarriorsDirectory(args[0]);
|
||||
}
|
||||
|
||||
var taskA = new Task(() =>
|
||||
{
|
||||
var nancyHost = new Nancy.Hosting.Self.NancyHost(new Uri(httpUrl), new CustomBootstrapper());
|
||||
nancyHost.Start();
|
||||
Console.WriteLine("Web server running...");
|
||||
|
||||
Process.Start(httpUrl);
|
||||
|
||||
|
||||
while (!ct.IsCancellationRequested) { Thread.Sleep(1000); }
|
||||
nancyHost.Stop();
|
||||
}, tokenSource.Token);
|
||||
|
||||
var taskB = new Task(() =>
|
||||
{
|
||||
var wssv = new WebSocketServer(websocketUrl);
|
||||
wssv.AddWebSocketService<r2warsWebSocket>("/r2wars");
|
||||
wssv.Start();
|
||||
while (!ct.IsCancellationRequested) { Thread.Sleep(1000); }
|
||||
wssv.Stop();
|
||||
}, tokenSource.Token);
|
||||
|
||||
taskA.Start();
|
||||
taskB.Start();
|
||||
Console.ReadKey();
|
||||
tokenSource.Cancel();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// La información general de un ensamblado se controla mediante el siguiente
|
||||
// conjunto de atributos. Cambie estos valores de atributo para modificar la información
|
||||
// asociada con un ensamblado.
|
||||
[assembly: AssemblyTitle("WindowsFormsApplication1")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("WindowsFormsApplication1")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Si establece ComVisible en false, los tipos de este ensamblado no estarán visibles
|
||||
// para los componentes COM. Si necesita obtener acceso a un tipo de este ensamblado desde
|
||||
// COM, establezca el atributo ComVisible en true en este tipo.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// El siguiente GUID sirve como id. de typelib si este proyecto se expone a COM.
|
||||
[assembly: Guid("7c07ab0a-d2b5-4546-b5b2-6dc6e77e40d1")]
|
||||
|
||||
// La información de versión de un ensamblado consta de los cuatro valores siguientes:
|
||||
//
|
||||
// Versión principal
|
||||
// Versión secundaria
|
||||
// Número de compilación
|
||||
// Revisión
|
||||
//
|
||||
// Puede especificar todos los valores o usar los valores predeterminados de número de compilación y de revisión
|
||||
// mediante el carácter '*', como se muestra a continuación:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
Generated
-63
@@ -1,63 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Este código fue generado por una herramienta.
|
||||
// Versión de runtime:4.0.30319.42000
|
||||
//
|
||||
// Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si
|
||||
// se vuelve a generar el código.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace r2warsTorneo.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clase de recurso fuertemente tipado, para buscar cadenas traducidas, etc.
|
||||
/// </summary>
|
||||
// StronglyTypedResourceBuilder generó automáticamente esta clase
|
||||
// a través de una herramienta como ResGen o Visual Studio.
|
||||
// Para agregar o quitar un miembro, edite el archivo .ResX y, a continuación, vuelva a ejecutar ResGen
|
||||
// con la opción /str o recompile su proyecto de VS.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve la instancia de ResourceManager almacenada en caché utilizada por esta clase.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("r2warsTorneo.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reemplaza la propiedad CurrentUICulture del subproceso actual para todas las
|
||||
/// búsquedas de recursos mediante esta clase de recurso fuertemente tipado.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Generated
-26
@@ -1,26 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Este código fue generado por una herramienta.
|
||||
// Versión de runtime:4.0.30319.42000
|
||||
//
|
||||
// Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si
|
||||
// se vuelve a generar el código.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace r2warsTorneo.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -1,40 +1,192 @@
|
||||
# r2wars
|
||||
|
||||
C# implementation for r2wars tournament
|
||||

|
||||
|
||||
Tournament api from: https://github.com/otac0n/tournaments
|
||||
r2wars is a Core War-style tournament powered by radare2 and ESIL. Two
|
||||
assembly warriors share a 1 KiB arena and take turns executing instructions.
|
||||
Each warrior tries to corrupt its opponent until the opponent crashes, traps,
|
||||
or leaves the arena.
|
||||
|
||||
## Description
|
||||
Warriors may target different CPU architectures while competing in the same
|
||||
address space.
|
||||
|
||||
r2wars is a game similar to corewars, where 2 programs run on a
|
||||
shared memory space trying to catch each other in order to trash
|
||||
their code and make them crash.
|
||||
## Choose how to run it
|
||||
|
||||
This game was initially developed by pancake as a PoC in here
|
||||
| Mode | Requirements | Execution | Best for |
|
||||
| --- | --- | --- | --- |
|
||||
| Docker | Docker with Compose | .NET and native radare2 in containers | Fastest local setup |
|
||||
| Native | .NET 10 and radare2 | Local .NET server and native radare2 | Development and full architecture support |
|
||||
| WebAssembly | Node.js/npm for building | Entirely inside the browser | Static hosting and serverless deployment |
|
||||
|
||||
* https://github.com/radare/radare2-extras/tree/master/r2wars
|
||||
The WebAssembly implementation is an alternative execution path. It does not
|
||||
replace or change the existing .NET and Docker flows.
|
||||
|
||||
You can find an explanation of the game in the first competition
|
||||
that happened during the 2nd r2con in 2017.
|
||||
## Quick start with Docker
|
||||
|
||||
* https://www.youtube.com/watch?v=sB-i5yUatx4
|
||||
From the repository root:
|
||||
|
||||
This repository contains an evolved implementation of the engine
|
||||
written in C# by SkUaTeR dropping the MFC requirement that was
|
||||
making it impossible to run outside Windows.
|
||||
```sh
|
||||
make start
|
||||
```
|
||||
|
||||
The solution was to use an embedded webserver that provides a
|
||||
web interface using websockets to stream the process changes
|
||||
from the M
|
||||
Open <http://127.0.0.1:9664/>. The local `warriors/` directory is mounted
|
||||
read-only into the container.
|
||||
|
||||
## Dependencies
|
||||
Useful commands:
|
||||
|
||||
* Mono / .NET Runtime
|
||||
* radare2
|
||||
```sh
|
||||
make build # build the Docker image
|
||||
make start # start r2wars and its nginx frontend
|
||||
make stop # stop the containers
|
||||
make clean # stop and remove the r2wars image
|
||||
```
|
||||
|
||||
On windows you need to have radare2.exe and rasm2.exe in the same
|
||||
directory as the r2wars.exe executable.
|
||||
The Docker image pins radare2 6.2.0 and verifies the official `amd64` or
|
||||
`arm64` release package before installing it.
|
||||
|
||||
On Mac/Linux/BSD, r2wars will try to find them in the PATH.
|
||||
## Run natively
|
||||
|
||||
--pancake
|
||||
Install the .NET 10 SDK and radare2, then run:
|
||||
|
||||
```sh
|
||||
dotnet run --project csharp/r2wars.csproj -- ../warriors
|
||||
```
|
||||
|
||||
Open <http://127.0.0.1:9664/>.
|
||||
|
||||
On Linux, macOS, and BSD, `radare2` and `rasm2` are loaded from `PATH`. On
|
||||
Windows, put `radare2.exe` and `rasm2.exe` in `PATH` or alongside the published
|
||||
r2wars application. The native interface uses the same bot manager and editor
|
||||
as the WebAssembly build; live previews are assembled by native `rasm2`.
|
||||
|
||||
## WebAssembly version
|
||||
|
||||
The browser version runs the tournament controller and radare2 ESIL locally in
|
||||
a Web Worker. It has no Kestrel or WebSocket connection, does not require
|
||||
Docker or .NET at runtime, and never uploads warrior source or tournament state.
|
||||
|
||||
### Build and run locally
|
||||
|
||||
```sh
|
||||
make wasm-build
|
||||
make wasm-run
|
||||
```
|
||||
|
||||
Then open <http://127.0.0.1:5173/>. The production site is generated in
|
||||
`wasm/dist/`.
|
||||
|
||||
The first build downloads the official radare2 6.2.0 WASI API module and
|
||||
verifies the checksums of both the release archive and extracted Wasm module.
|
||||
The module is about 44 MB before HTTP or ZIP compression.
|
||||
|
||||
### Create a deployable ZIP
|
||||
|
||||
```sh
|
||||
make wasm-dist
|
||||
```
|
||||
|
||||
This creates `wasm/r2wars-wasm.zip`. The archive contains the complete static
|
||||
site with `index.html` at its root:
|
||||
|
||||
```text
|
||||
index.html
|
||||
radare2.wasm
|
||||
assets/
|
||||
warriors/
|
||||
```
|
||||
|
||||
Extract those files directly into a static server's document root. No
|
||||
application backend, .NET runtime, radare2 installation, or WebSocket proxy is
|
||||
needed. The paths are relative, so the site can also be hosted below a URL
|
||||
prefix.
|
||||
|
||||
The server should deliver `.wasm` files as `application/wasm`. Opening
|
||||
`index.html` through `file://` is not supported because browsers restrict local
|
||||
Wasm and module loading; use any ordinary HTTP(S) static server instead.
|
||||
|
||||
You can choose a different archive name when needed:
|
||||
|
||||
```sh
|
||||
make wasm-dist WASM_ARCHIVE=my-r2wars-build.zip
|
||||
```
|
||||
|
||||
### Shared web controls
|
||||
|
||||
- The WebAssembly build initially loads three bundled bots. The .NET build
|
||||
loads the configured warriors directory.
|
||||
- Open **Bots** while the tournament is not running to inspect the complete
|
||||
roster, create or import bots, rename them, edit their assembly, or remove
|
||||
them.
|
||||
- Bot edits are drafts. They do not modify a running or paused tournament and
|
||||
are validated and loaded only when **Start new tournament** is selected.
|
||||
- Every filename or source edit is assembled immediately by the selected
|
||||
engine—radare2 Wasm in the static build or native `rasm2` in the .NET build.
|
||||
The editor shows a red or green result, the compiled size, and the complete
|
||||
byte array; results over the 512-byte warrior limit are marked red.
|
||||
- Select **Choose warriors** to replace the draft roster with local `.asm`
|
||||
files. Dropping `.asm` files onto the page adds or updates bots by filename.
|
||||
- Tournaments support run, pause, single-cycle stepping, bounded history,
|
||||
standings, and downloadable reports.
|
||||
- In the WebAssembly build, tournament execution stays in a worker so the
|
||||
interface remains responsive.
|
||||
|
||||
### Browser architecture support
|
||||
|
||||
The official radare2 6.2.0 WASI module contains x86, ARM, MIPS, RISC-V, and
|
||||
Game Boy support. It does not contain the 8051 plugin, so 8051 warriors require
|
||||
the native or Docker version for now.
|
||||
|
||||
See [wasm/README.md](wasm/README.md) for implementation details and direct npm
|
||||
commands.
|
||||
|
||||
## Writing warriors
|
||||
|
||||
A tournament requires at least two non-empty `.asm` files. The architecture
|
||||
and bitness are encoded before the `.asm` extension:
|
||||
|
||||
```text
|
||||
scanner.x86-32.asm
|
||||
hammer.arm-64.asm
|
||||
probe.mips-32.asm
|
||||
```
|
||||
|
||||
Supported filename markers are:
|
||||
|
||||
- `.x86-32.asm` and `.x86-64.asm`
|
||||
- `.arm-16.asm`, `.arm-32.asm`, and `.arm-64.asm`
|
||||
- `.mips-32.asm` and `.mips-64.asm`
|
||||
- `.riscv-32.asm` and `.riscv-64.asm`
|
||||
- `.gb.asm`
|
||||
- `.8051.asm` in the native and Docker versions
|
||||
|
||||
Examples for several architectures are available in `examples/`. The default
|
||||
native and Docker tournament reads warriors from `warriors/`.
|
||||
|
||||
## WebAssembly development commands
|
||||
|
||||
Run these from the repository root:
|
||||
|
||||
```sh
|
||||
make wasm-test # test parsers and the engine against the real radare2 Wasm
|
||||
make wasm-build # type-check and build wasm/dist/
|
||||
make wasm-run # start the Vite development server
|
||||
make wasm-dist # build and package wasm/r2wars-wasm.zip
|
||||
```
|
||||
|
||||
The dedicated WebAssembly CI workflow runs the tests and production build, then
|
||||
uploads `wasm/dist/` as the `r2wars-wasm` artifact.
|
||||
|
||||
## Background
|
||||
|
||||
The original proof of concept lives in
|
||||
[radare2-extras](https://github.com/radare/radare2-extras/tree/master/r2wars).
|
||||
This repository evolved the engine into a portable C# implementation by
|
||||
SkUaTeR, replacing the original Windows-only MFC interface with a web UI.
|
||||
|
||||
Further introductions:
|
||||
|
||||
- [r2wars for N00bs — r2con 2020](https://www.youtube.com/watch?v=PB0AFBqFwGQ)
|
||||
- [r2wars competition — r2con 2017](https://www.youtube.com/watch?v=sB-i5yUatx4)
|
||||
- [Tournament library](https://github.com/otac0n/tournaments)
|
||||
|
||||
— pancake
|
||||
+2
-2
@@ -12,8 +12,8 @@ supporting other architectures with ESIL as emulation engine.
|
||||
Introduction
|
||||
------------
|
||||
|
||||
In order to start the competition you need to run r2wars.exe
|
||||
which is written in C# and runs on Mono, .NET/Core or MSCLR.
|
||||
In order to start the competition you need the ASP.NET Core Runtime 10,
|
||||
then run `dotnet r2wars.dll [warriors-directory]`.
|
||||
|
||||
The UI has been rewritten from the original MFC to be in HTML,
|
||||
so the program will run a local webserver which serves a
|
||||
|
||||
@@ -1,358 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
public class Torneo
|
||||
{
|
||||
string warriorsDirectory = "warriors";
|
||||
static List<TournamentTeam> teams = new List<TournamentTeam>();
|
||||
static List<TournamentRound> rounds = new List<TournamentRound>();
|
||||
static Dictionary<long, string> teamNames = new Dictionary<long, string>();
|
||||
static Dictionary<long, string> teamWarriors = new Dictionary<long, string>();
|
||||
static r2wars r2w = null;
|
||||
RoundRobinPairingsGenerator generator;
|
||||
List<TournamentPairing> allcombats = new List<TournamentPairing>();
|
||||
|
||||
TournamentTeamScore[] actualcombatscore = { null, null };
|
||||
int ncombat = 0;
|
||||
string[] actualcombatnames = { "", "" };
|
||||
string[] actualcombatwarriors = { "", "" };
|
||||
|
||||
public string fullCombatLog ="";
|
||||
public string stats ="";
|
||||
public string actualCombatLog = "";
|
||||
|
||||
public bool bTournamentRun = false;
|
||||
private clsEngine.eArch tournamenArch = clsEngine.eArch.x86;
|
||||
|
||||
Task tournamentTask = null;
|
||||
bool bTournamenTask = false;
|
||||
bool bCombatEnd = true;
|
||||
|
||||
public Torneo()
|
||||
{
|
||||
r2w = r2warsStatic.r2w;
|
||||
}
|
||||
public void SetWarriorsDirectory(string wd) {
|
||||
this.warriorsDirectory = wd;
|
||||
}
|
||||
|
||||
private void espera(int veces, int pausa = 1)
|
||||
{
|
||||
Task t = Task.Factory.StartNew(() =>
|
||||
{
|
||||
int n = veces;
|
||||
while ((n--) > 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(pausa);
|
||||
}
|
||||
});
|
||||
t.Wait();
|
||||
}
|
||||
|
||||
|
||||
void drawstats()
|
||||
{
|
||||
stats= string.Format("Combat {0} / {1}", ncombat ,allcombats.Count) + Environment.NewLine;
|
||||
var standings = generator.GenerateRankings();
|
||||
|
||||
foreach (var standing in standings)
|
||||
{
|
||||
string salida = string.Format("{0} {1} {2}", standing.Rank.ToString(), teamNames[standing.Team.TeamId], standing.ScoreDescription);
|
||||
stats+= salida + Environment.NewLine;
|
||||
}
|
||||
r2w.send_draw_event(r2w.json_output());
|
||||
r2w.send_draw_event("on");
|
||||
|
||||
}
|
||||
|
||||
private void RoundEnd(object sender, MyEvent e)
|
||||
{
|
||||
|
||||
int nround = e.round + 1;
|
||||
fullCombatLog += " Round-" + nround.ToString() + " " + r2w.Engine.players[e.ganador].name + " Wins Cycles:" + e.ciclos.ToString() + Environment.NewLine;
|
||||
actualCombatLog += " Round-" + nround.ToString() + " " + r2w.Engine.players[e.ganador].name + " Wins Cycles:" + e.ciclos.ToString() + Environment.NewLine;
|
||||
|
||||
if (actualcombatscore[e.ganador].Score!=null)
|
||||
actualcombatscore[e.ganador].Score+= new HighestPointsScore(1);
|
||||
r2w.send_draw_event(r2w.json_output());
|
||||
|
||||
/*Task t = Task.Factory.StartNew(() =>
|
||||
{
|
||||
int n = 10;
|
||||
while ((n--) > 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
Console.WriteLine("Round end Waiting ...");
|
||||
}
|
||||
});
|
||||
t.Wait();*/
|
||||
}
|
||||
|
||||
private void RoundExhausted(object sender, MyEvent e)
|
||||
{
|
||||
int nround = e.round + 1;
|
||||
actualCombatLog += " Round-" + nround.ToString() + " TIMEOUT Cycles:" + e.ciclos.ToString() + Environment.NewLine;
|
||||
fullCombatLog += " Round-" + nround.ToString() + " TIMEOUT Cycles:" + e.ciclos.ToString() + Environment.NewLine;
|
||||
|
||||
}
|
||||
private void CombatEnd(object sender, MyEvent e)
|
||||
{
|
||||
string ganador = "";
|
||||
if (r2w.victorias[0] == 2)
|
||||
ganador = r2w.Engine.players[0].name;
|
||||
if (r2w.victorias[1] == 2)
|
||||
ganador = r2w.Engine.players[1].name;
|
||||
int ciclos = r2w.totalciclos;
|
||||
actualCombatLog += "Combat Winner: " + ganador + Environment.NewLine;
|
||||
fullCombatLog += "Combat Winner: " + ganador + Environment.NewLine;
|
||||
|
||||
|
||||
ncombat++;
|
||||
drawstats();
|
||||
espera(1000);
|
||||
r2w.send_draw_event("off");
|
||||
bCombatEnd = true;
|
||||
}
|
||||
void runnextcombat(bool startcombat)
|
||||
{
|
||||
if (ncombat < allcombats.Count)
|
||||
{
|
||||
int j = 0;
|
||||
foreach (var teamScore in allcombats[ncombat].TeamScores)
|
||||
{
|
||||
actualcombatnames[j] = teamNames[teamScore.Team.TeamId];
|
||||
actualcombatwarriors[j] = teamWarriors[teamScore.Team.TeamId];
|
||||
actualcombatscore[j] = teamScore;
|
||||
actualcombatscore[j].Score += new HighestPointsScore(0);
|
||||
j++;
|
||||
}
|
||||
string tmp = string.Format("Iniciando combate {0} {1} vs {2}", ncombat + 1, actualcombatnames[0], actualcombatnames[1]);
|
||||
actualCombatLog = tmp + Environment.NewLine;
|
||||
fullCombatLog += tmp + Environment.NewLine;
|
||||
bCombatEnd = false;
|
||||
|
||||
r2w.playcombat(actualcombatwarriors[0], actualcombatwarriors[1], actualcombatnames[0], actualcombatnames[1], startcombat, false, tournamenArch);
|
||||
}
|
||||
else
|
||||
{
|
||||
fullCombatLog += "Tournament end " + DateTime.Now + Environment.NewLine;
|
||||
bTournamentRun = false;
|
||||
r2w.send_draw_event(r2w.json_output());
|
||||
}
|
||||
}
|
||||
public void StopTournament()
|
||||
{
|
||||
while (bTournamenTask == true)
|
||||
{
|
||||
bTournamentRun = false;
|
||||
bCombatEnd = true;
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
private void dopairs(string[] selectedfiles, string strarch, string extension)
|
||||
{
|
||||
generator = new RoundRobinPairingsGenerator();
|
||||
generator.Reset();
|
||||
int n = 0;
|
||||
foreach (string s in selectedfiles)
|
||||
{
|
||||
var team = new TournamentTeam(n, 0);
|
||||
teams.Add(team);
|
||||
string tmp = Path.GetFileName(selectedfiles[n]);
|
||||
teamNames.Add(n, tmp.Substring(0, tmp.IndexOf(extension)));
|
||||
teamWarriors.Add(n, selectedfiles[n]);
|
||||
n++;
|
||||
}
|
||||
// generamos todas las rondas.
|
||||
while (true)
|
||||
{
|
||||
TournamentRound round = null;
|
||||
generator.Reset();
|
||||
generator.LoadState(teams, rounds);
|
||||
round = generator.CreateNextRound(null);
|
||||
if (round != null)
|
||||
{
|
||||
rounds.Add(round);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach (TournamentRound round in rounds)
|
||||
{
|
||||
foreach (var pairing in round.Pairings)
|
||||
{
|
||||
allcombats.Add(pairing);
|
||||
}
|
||||
}
|
||||
|
||||
string memoria = "";
|
||||
for (int x = 0; x < 1024; x++)
|
||||
memoria += "\"\"" + ",";
|
||||
memoria = memoria.Remove(memoria.Length - 1);
|
||||
|
||||
string salida = "";
|
||||
salida = "Tournament arch: " + strarch + "\nTotal Warriors loaded " + selectedfiles.Count().ToString() +"\nPress 'start' button to begin tournament." ;
|
||||
string envio = "{\"player1\":{\"regs\":\"\",\"code\":\"\",\"name\":\"Player - 1\"},\"player2\":{\"regs\":\"\",\"code\":\"\",\"name\":\"Player - 2\"},\"memory\":[" + memoria + "],\"console\":\"" + salida + "\",\"status\":\"Warriors Loaded.\",\"scores\":\"\"}";
|
||||
r2w.send_draw_event(envio.Replace("\n", "\\n").Replace("\r", ""));
|
||||
r2w.totalciclos = 0;
|
||||
}
|
||||
public void LoadTournamentPlayers()
|
||||
{
|
||||
StopTournament();
|
||||
r2w.StopCombate();
|
||||
|
||||
if (bTournamentRun == false)
|
||||
{
|
||||
allcombats.Clear();
|
||||
teamNames.Clear();
|
||||
teamWarriors.Clear();
|
||||
rounds.Clear();
|
||||
teams.Clear();
|
||||
ncombat = 0;
|
||||
if (r2w != null)
|
||||
{
|
||||
r2w.Event_combatEnd -= new MyHandler1(CombatEnd);
|
||||
r2w.Event_combatEnd += new MyHandler1(CombatEnd);
|
||||
|
||||
r2w.Event_roundEnd -= new MyHandler1(RoundEnd);
|
||||
r2w.Event_roundEnd += new MyHandler1(RoundEnd);
|
||||
|
||||
r2w.Event_roundExhausted -= new MyHandler1(RoundExhausted);
|
||||
r2w.Event_roundExhausted += new MyHandler1(RoundExhausted);
|
||||
}
|
||||
|
||||
r2w.nRound = 0;
|
||||
r2w.victorias[0] = 0;
|
||||
r2w.victorias[1] = 0;
|
||||
r2w.bDead = false;
|
||||
fullCombatLog = "";
|
||||
|
||||
|
||||
|
||||
string[] files = Directory.GetFiles(warriorsDirectory);
|
||||
string[] selectedfiles = null;
|
||||
string extension = "";
|
||||
string[] arm32 = files.Where(p => p.EndsWith(".arm-32.asm")).ToArray();
|
||||
string[] x8632 = files.Where(p => p.EndsWith(".x86-32.asm")).ToArray();
|
||||
string[] mips64 = files.Where(p => p.EndsWith(".mips-64.asm")).ToArray();
|
||||
string strarch = "";
|
||||
int n = 0;
|
||||
if (arm32.Count() > 0 && x8632.Count() > 0)
|
||||
{
|
||||
Console.Write("Detected mixed archs.\nWhat do you want to run:\n 1) arm 32 bit\n 2) x86 32 bit\n\n 0) exit\n\nSelect option:");
|
||||
r2w.answer = "";
|
||||
r2w.send_draw_event("askarch");
|
||||
Task t = Task.Factory.StartNew(() =>
|
||||
{
|
||||
while (r2w.answer == "")
|
||||
Thread.Sleep(10);
|
||||
if (r2w.answer == "arm")
|
||||
{
|
||||
selectedfiles = arm32;
|
||||
extension = ".arm-32.asm";
|
||||
tournamenArch = clsEngine.eArch.arm32;
|
||||
strarch = "arm 32 bits.";
|
||||
}
|
||||
else if (r2w.answer == "x86")
|
||||
{
|
||||
selectedfiles = x8632;
|
||||
extension = ".x86-32.asm";
|
||||
tournamenArch = clsEngine.eArch.x86;
|
||||
strarch = "x86 32 bits.";
|
||||
}
|
||||
else
|
||||
return;
|
||||
dopairs(selectedfiles, strarch, extension);
|
||||
});
|
||||
return;
|
||||
}
|
||||
else if (mips64.Count() > 0)
|
||||
{
|
||||
selectedfiles = arm32;
|
||||
extension = ".mips-64.asm";
|
||||
tournamenArch = clsEngine.eArch.mips64;
|
||||
strarch = "mips 64 bits.";
|
||||
}
|
||||
else if (arm32.Count() > 0)
|
||||
{
|
||||
selectedfiles = arm32;
|
||||
extension = ".arm-32.asm";
|
||||
tournamenArch = clsEngine.eArch.arm32;
|
||||
strarch = "arm 32 bits.";
|
||||
}
|
||||
else if (x8632.Count() > 0)
|
||||
{
|
||||
selectedfiles = x8632;
|
||||
extension = ".x86-32.asm";
|
||||
tournamenArch = clsEngine.eArch.x86;
|
||||
strarch = "x86 32 bits.";
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Warriors dont found. plz copy inside this folder '.x86-32' or '.arm-32' warriors.");
|
||||
return;
|
||||
}
|
||||
dopairs(selectedfiles, strarch, extension);
|
||||
}
|
||||
}
|
||||
public void StopActualCombat()
|
||||
{
|
||||
r2w.StopCombate();
|
||||
}
|
||||
public void StepTournamentCombats()
|
||||
{
|
||||
if (bTournamentRun == false)
|
||||
{
|
||||
RunTournamentCombats(false);
|
||||
r2w.bInCombat = true;
|
||||
}
|
||||
else if (r2w.bThreadIni == false)
|
||||
{
|
||||
|
||||
r2w.stepCombate();
|
||||
}
|
||||
}
|
||||
public void RunTournamentCombats(bool startcombat)
|
||||
{
|
||||
|
||||
if (bTournamentRun == false)
|
||||
{
|
||||
fullCombatLog = "Tournament start " + DateTime.Now + Environment.NewLine;
|
||||
bTournamentRun = true;
|
||||
tournamentTask = Task.Factory.StartNew(() =>
|
||||
{
|
||||
bool firsttime = true;
|
||||
bTournamenTask = true;
|
||||
System.Diagnostics.Debug.WriteLine("TournamenTask: Ini.");
|
||||
while (bTournamentRun)
|
||||
{
|
||||
if (bCombatEnd == true)
|
||||
{
|
||||
if (firsttime && !startcombat)
|
||||
runnextcombat(false);
|
||||
else
|
||||
runnextcombat(true);
|
||||
}
|
||||
else
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
bTournamenTask = false;
|
||||
System.Diagnostics.Debug.WriteLine("TournamenTask: Fin.");
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
r2w.iniciaCombate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,516 +0,0 @@
|
||||
<html>
|
||||
|
||||
<script>
|
||||
var clicked = false;
|
||||
var clicked1 = false;
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
$('reset').addEventListener('click', () => {
|
||||
socket.send("reset_tournament");
|
||||
document.getElementById("start").innerHTML = "start";
|
||||
clicked = false;
|
||||
});
|
||||
$('start').addEventListener('click', () => {
|
||||
if (clicked === false) {
|
||||
socket.send("start_tournament");
|
||||
document.getElementById("start").innerHTML ="pause";
|
||||
clicked = true;
|
||||
}
|
||||
else if (clicked === true) {
|
||||
document.getElementById("start").innerHTML ="continue";
|
||||
socket.send("stop_tournament");
|
||||
clicked = false;
|
||||
}
|
||||
});
|
||||
$('next').addEventListener('click', () => {
|
||||
socket.send("next");
|
||||
|
||||
});
|
||||
$('buffer').addEventListener('click', () => {
|
||||
on();
|
||||
});
|
||||
$('lt').addEventListener('click', () => {
|
||||
socket.send("prevlog");
|
||||
|
||||
});
|
||||
$('gt').addEventListener('click', () => {
|
||||
socket.send("nextlog");
|
||||
});
|
||||
$('x86').addEventListener('click', () => {
|
||||
hideArchDlg();
|
||||
socket.send("arch_x86")
|
||||
});
|
||||
$('arm').addEventListener('click', () => {
|
||||
hideArchDlg();
|
||||
socket.send("arch_arm")
|
||||
});
|
||||
updateUI();
|
||||
});
|
||||
|
||||
|
||||
var state = {};
|
||||
|
||||
resetState();
|
||||
|
||||
var socket = new WebSocket('ws://localhost:9966/r2wars');
|
||||
socket.onopen = function ()
|
||||
{
|
||||
};
|
||||
socket.onclose = function ()
|
||||
{
|
||||
};
|
||||
|
||||
socket.onmessage = function (evt) {
|
||||
//alert(evt.data);
|
||||
if (evt.data !== "none") {
|
||||
|
||||
if (evt.data == "on") {
|
||||
on();
|
||||
}
|
||||
else if (evt.data == "off") {
|
||||
off();
|
||||
}
|
||||
else if (evt.data == "askarch") {
|
||||
showArchDlg();
|
||||
}
|
||||
else {
|
||||
state = JSON.parse(evt.data);
|
||||
updateUI();
|
||||
//socket.send("moreflow");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function resetState() {
|
||||
state = {
|
||||
player1: {
|
||||
regs: '',
|
||||
code: '',
|
||||
name: 'Player - 1',
|
||||
},
|
||||
player2: {
|
||||
regs: '',
|
||||
code: '',
|
||||
name: 'Player - 2',
|
||||
},
|
||||
memory: [
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
],
|
||||
console: '[r2wars]',
|
||||
status: 'idle',
|
||||
scores: ''
|
||||
};
|
||||
}
|
||||
|
||||
function updateUI() {
|
||||
var memory = memoryWidget();
|
||||
$('memory').innerHTML = memory;
|
||||
$('status').innerHTML = state.status;
|
||||
$('console').innerHTML = state.console;
|
||||
$('regs1').innerHTML = state.player1.regs;
|
||||
$('code1').innerHTML = state.player1.code;
|
||||
$('regs2').innerHTML = state.player2.regs;
|
||||
$('code2').innerHTML = state.player2.code;
|
||||
$('player1').innerHTML = state.player1.name;
|
||||
$('player2').innerHTML = state.player2.name;
|
||||
$('scores').innerHTML = state.scores;
|
||||
|
||||
}
|
||||
|
||||
function addrForRow(x) {
|
||||
return "0x" + ("0000" + x.toString(16)).substr(-4);
|
||||
}
|
||||
|
||||
function styler(x) {
|
||||
var color='white';
|
||||
switch(x) {
|
||||
case 'r': color='red'; break;
|
||||
case 'y': color='yellow'; break;
|
||||
case 'g': color='green'; break;
|
||||
case 'w': color='white'; break;
|
||||
case 'n': color='black'; break;
|
||||
case 'b': color='blue'; break;
|
||||
case 'q': color='aqua'; break;
|
||||
case 'o': color='orange'; break;
|
||||
case 'v': color='violet'; break;
|
||||
}
|
||||
return 'background-color:'+ color;
|
||||
}
|
||||
|
||||
function memoryWidget() {
|
||||
var a = '<table class="memtable">';
|
||||
var rows = 32;
|
||||
var rowlen = 32;
|
||||
for (i = 0; i<rows; i++) {
|
||||
var addr = addrForRow(i * rowlen);
|
||||
var row = "";
|
||||
for (j = 0; j <rowlen;j++) {
|
||||
var s = state.memory[(i * rowlen) + j];
|
||||
var ch = ((s&&s.length) > 1)? s[1]: ' ';
|
||||
var style = (s&&s.length > 0)? styler(s[0]): '';
|
||||
row += '<td style="'+style+'" class="box">'+ch+'</td>'
|
||||
}
|
||||
a += "<tr><td class='addr'>"+addr+"</td>"+row+"</tr>";
|
||||
}
|
||||
return a + '</table>';
|
||||
}
|
||||
|
||||
function $(x) {
|
||||
return document.getElementById(x);
|
||||
}
|
||||
|
||||
function Query(c, cb) {
|
||||
Ajax('GET', '/r2wars/' + encodeURI(c), '', function(x) { if (cb) { cb(x); } });
|
||||
}
|
||||
var ajax_in_process = false;
|
||||
function Ajax(method, uri, body, fn) {
|
||||
if (typeof (XMLHttpRequest) == 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('async waiting');
|
||||
if (ajax_in_process) {
|
||||
setTimeout(function() {
|
||||
Ajax(method, uri, body, fn);
|
||||
}, 100);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var x = new XMLHttpRequest();
|
||||
|
||||
if (!x) {
|
||||
return false;
|
||||
}
|
||||
ajax_in_process = true;
|
||||
|
||||
x.open(method, uri, false);
|
||||
|
||||
x.setRequestHeader('Accept', 'text/plain');
|
||||
x.setRequestHeader ('Accept', 'text/html');
|
||||
x.onreadystatechange = function() {
|
||||
ajax_in_process = false;
|
||||
if (x.status == 200) {
|
||||
if (fn) {
|
||||
fn(x.responseText);
|
||||
} else {
|
||||
console.error('missing ajax callback');
|
||||
}
|
||||
} else {
|
||||
console.error('ajax ' + x.status);
|
||||
}
|
||||
};
|
||||
x.send(null);
|
||||
}
|
||||
function on() {
|
||||
document.getElementById("overlay").style.display = "block";
|
||||
}
|
||||
|
||||
function off() {
|
||||
document.getElementById("overlay").style.display = "none";
|
||||
}
|
||||
function showArchDlg() {
|
||||
document.getElementById("askarchdlg").style.display = "block";
|
||||
}
|
||||
|
||||
function hideArchDlg() {
|
||||
document.getElementById("askarchdlg").style.display = "none";
|
||||
}
|
||||
display: none;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
table {
|
||||
}
|
||||
|
||||
button {
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.addr {
|
||||
color:white;
|
||||
background-color:black;
|
||||
}
|
||||
|
||||
.memory {
|
||||
overflow-y: scroll;
|
||||
height:100%;
|
||||
}
|
||||
|
||||
.box {
|
||||
width:1em;
|
||||
height:1em;
|
||||
color: white;
|
||||
background-color:#a0a0a0;
|
||||
}
|
||||
|
||||
.console {
|
||||
height: 200px;
|
||||
background-color:black;
|
||||
color:white;
|
||||
font-family: Courier New;
|
||||
font-weight:bold;
|
||||
white-space: pre;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.console1 {
|
||||
height: 200px;
|
||||
background-color:black;
|
||||
color:white;
|
||||
font-family: Courier New;
|
||||
font-weight:bold;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.console2 {
|
||||
height: 400px;
|
||||
background-color:black;
|
||||
color:green;
|
||||
font-family: Courier New;
|
||||
font-weight:bold;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.s {
|
||||
background-color:green;
|
||||
color:black;
|
||||
font-family: Courier New;
|
||||
font-weight:bold;
|
||||
white-space: pre;
|
||||
}
|
||||
body {
|
||||
background-color:#c0c0c0;
|
||||
}
|
||||
|
||||
td {
|
||||
font-family: Courier New;
|
||||
border: 1px solid #a0a0a0;
|
||||
}
|
||||
div {
|
||||
font-family: Courier New;
|
||||
}
|
||||
tr {
|
||||
background-color:#e0e0e0;
|
||||
}
|
||||
.player1 {
|
||||
background-color:blue;
|
||||
color:white;
|
||||
font-weight:bold;
|
||||
font-size:2em;
|
||||
font-family: Courier New;
|
||||
text-align:center;
|
||||
}
|
||||
.player2 {
|
||||
color:white;
|
||||
background-color:red;
|
||||
font-weight:bold;
|
||||
font-size:2em;
|
||||
font-family: Courier New;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.memtable {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
display: none;
|
||||
top: 1%;
|
||||
left: 30%;
|
||||
right: 30%;
|
||||
bottom: 27%;
|
||||
background-color:rgba(0, 0, 0, 0.9);
|
||||
z-index: 2;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #a0a0a0
|
||||
}
|
||||
|
||||
.text{
|
||||
position: absolute;
|
||||
top: 4%;
|
||||
left: 50%;
|
||||
font-size: 40px;
|
||||
color: green;
|
||||
transform: translate(-50%,-50%);
|
||||
-ms-transform: translate(-50%,-50%);
|
||||
}
|
||||
.text1{
|
||||
position: absolute;
|
||||
top: 14%;
|
||||
left: 50%;
|
||||
font-size: 20px;
|
||||
color: green;
|
||||
transform: translate(-50%,0%);
|
||||
-ms-transform: translate(-50%,0%);
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.win98{
|
||||
display: none;
|
||||
top: 30%;
|
||||
left: 30%;
|
||||
right: 30%;
|
||||
z-index: 3;
|
||||
-webkit-font-smoothing: none;
|
||||
-moz-osx-font-smoothing: none;
|
||||
font-size: 11px;
|
||||
font-family: Tahoma, Verdana;
|
||||
color: #070707;
|
||||
position: absolute;
|
||||
margin: 0 auto;
|
||||
background: #bfbfbf;
|
||||
border: 1px solid;
|
||||
border-top-color: #dfdfdf;
|
||||
border-left-color: #dfdfdf;
|
||||
border-right-color: #808080;
|
||||
border-bottom-color: #808080;
|
||||
box-shadow: 1px 1px 0 0 #000;
|
||||
width: 400px;
|
||||
cursor: default;
|
||||
}
|
||||
.win98 .content {
|
||||
padding: 7px 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.win98 .header {
|
||||
margin: 2px 2px 0;
|
||||
padding: 1px 2px;
|
||||
color: #fff;
|
||||
background: -webkit-linear-gradient(left, blue, red);
|
||||
background: linear-gradient(to right, blue, red);
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.win98 button {
|
||||
-webkit-font-smoothing: none;
|
||||
-moz-osx-font-smoothing: none;
|
||||
font-size: 11px;
|
||||
font-family: Tahoma, Verdana;
|
||||
color: #070707;
|
||||
background: #bfbfbf;
|
||||
border: 1px solid;
|
||||
border-top-color: #dfdfdf;
|
||||
border-left-color: #dfdfdf;
|
||||
border-right-color: #808080;
|
||||
border-bottom-color: #808080;
|
||||
box-shadow: 1px 1px 0 0 #000;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
padding: 4px;
|
||||
cursor: default;
|
||||
font-size: 16px;
|
||||
}
|
||||
.win98 button:enabled {
|
||||
color: #070707;
|
||||
}
|
||||
.win98 button:disabled {
|
||||
color: #818181;
|
||||
text-shadow: 1px 1px #fff;
|
||||
}
|
||||
.win98 button:active:enabled {
|
||||
box-shadow: 1px 1px 0 0 #000 inset;
|
||||
border-top-color: #808080;
|
||||
border-left-color: #808080;
|
||||
border-right-color: #dfdfdf;
|
||||
border-bottom-color: #dfdfdf;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="overlay" class="overlay" onclick="off()">
|
||||
<div class="text">Score Board</div>
|
||||
<div id="scores" class="text1"></div>
|
||||
</div>
|
||||
|
||||
<div id="askarchdlg" class='win98'>
|
||||
<div class='header'>
|
||||
Multiple warriors detected:
|
||||
</div>
|
||||
<div class='content'>
|
||||
<center>
|
||||
<h3>What Arch do you want to run?</h3>
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<td><button id="arm">ARM 32 bits</button></td>
|
||||
<td><button id="x86">X86 32 bits</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<table style="width:100%;height:100%">
|
||||
<tr>
|
||||
|
||||
<td style="width:30%">
|
||||
<table style="height:100%;width:100%">
|
||||
<tr>
|
||||
<td class="player1" id=player1>Player 1</td>
|
||||
</tr>
|
||||
<tr style="height:100%">
|
||||
<td valign=top>
|
||||
<div class=console1 id=regs1>regs</div>
|
||||
<div style="border: 1px solid #a0a0a0"></div>
|
||||
<div class=console2 id=code1>code</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
<td style="width:30%">
|
||||
<table style="height:100%;width:100%">
|
||||
<tr style="height:100%">
|
||||
<td valign=top><div class=memory id=memory>memory</div></td>
|
||||
</tr>
|
||||
<tr style="height:100%">
|
||||
<td>
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<td><button id="reset">Load Warriors</button></td>
|
||||
<td><button id="start">Start</button></td>
|
||||
<td><button id="next">Next</button></td>
|
||||
<td><button id="buffer">Scores</button></td>
|
||||
<td><button id="lt"><</button></td>
|
||||
<td><button id="gt">></button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="height:100%">
|
||||
<td><div id="console" class="console">console</div></td>
|
||||
</tr>
|
||||
<tr style="height:100%">
|
||||
<td id="status">status</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
<td style="width:30%">
|
||||
<table style="height:100%;width:100%">
|
||||
<tr>
|
||||
<td class="player2" id=player2>Player 2</td>
|
||||
</tr>
|
||||
<tr style="height:100%">
|
||||
<td valign=top height="100%">
|
||||
<div class=console1 id=regs2>regs</div>
|
||||
<div style="border: 1px solid #a0a0a0"></div>
|
||||
<div class=console2 id=code2>code</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
-894
@@ -1,894 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
public class clsinfo
|
||||
{
|
||||
public string pc = "";
|
||||
public string ins = "";
|
||||
public string dasm = "";
|
||||
public string regs = "";
|
||||
public string mem = "";
|
||||
public string txtmemoria = "";
|
||||
public int cycles = 0;
|
||||
public bool dead = false;
|
||||
|
||||
public clsinfo(string pc, string ins, string dasm, string regs, string mem, int cycles, string txtmemoria)
|
||||
{
|
||||
this.pc = pc;
|
||||
this.ins = ins;
|
||||
this.dasm = dasm;
|
||||
this.regs = regs;
|
||||
this.mem = mem;
|
||||
this.cycles = cycles;
|
||||
this.txtmemoria = txtmemoria;
|
||||
}
|
||||
public int ipc()
|
||||
{
|
||||
if (pc != "")
|
||||
{
|
||||
int ipc = Convert.ToInt32(pc.Substring(3), 16);
|
||||
return ipc;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public string formatregs()
|
||||
{
|
||||
string[] reg = regs.Split('\n');
|
||||
string regformat = "";
|
||||
int x = 0;
|
||||
foreach (string s in reg)
|
||||
{
|
||||
if (s.StartsWith("oeax") == false)
|
||||
{
|
||||
if (x % 3 == 0 && x != 0)
|
||||
regformat += "\n";
|
||||
regformat += s + " ";
|
||||
x++;
|
||||
}
|
||||
}
|
||||
return regformat;
|
||||
}
|
||||
}
|
||||
public class player
|
||||
{
|
||||
public string name = "";
|
||||
public int orig = 0;
|
||||
public int size = 0;
|
||||
public string user = "";
|
||||
public string code = "";
|
||||
public string userini = "";
|
||||
public int cycles = 0;
|
||||
public int cyclesfixed = 0;
|
||||
public clsinfo actual;
|
||||
|
||||
public List<clsinfo> log;
|
||||
int idxlog;
|
||||
public player(string name, int orig, int size, string code, string user, int ciclos) //,string dasm,string mem,string ins, string pc, string reg)
|
||||
{
|
||||
this.name = name;
|
||||
this.orig = orig;
|
||||
this.size = size;
|
||||
this.user = user;
|
||||
this.code = code;
|
||||
this.userini = user;
|
||||
this.cycles = ciclos;
|
||||
this.cyclesfixed = ciclos;
|
||||
this.log = new List<clsinfo>();
|
||||
this.actual = new clsinfo("", "", "", "", "", 0,"");
|
||||
idxlog = -1;
|
||||
}
|
||||
|
||||
|
||||
public void logClear()
|
||||
{
|
||||
log.Clear();
|
||||
idxlog = 0;
|
||||
}
|
||||
public void logAdd(clsinfo entry)
|
||||
{
|
||||
log.Add(entry);
|
||||
idxlog = log.Count();
|
||||
}
|
||||
public string logGetFull()
|
||||
{
|
||||
string res = "";
|
||||
for (int x = 0; x < log.Count; x++)
|
||||
{
|
||||
res += log[x].formatregs() + "\n" + log[x].dasm + "\n";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public clsinfo logGetPrev()
|
||||
{
|
||||
if (idxlog <0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (idxlog > 0)
|
||||
{
|
||||
idxlog--;
|
||||
}
|
||||
return log[idxlog];
|
||||
}
|
||||
public clsinfo logGetNext()
|
||||
{
|
||||
if (idxlog < 0 || idxlog>log.Count-1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (idxlog < log.Count - 1)
|
||||
{
|
||||
idxlog++;
|
||||
}
|
||||
return log[idxlog];
|
||||
}
|
||||
}
|
||||
|
||||
public class clsEngine
|
||||
{
|
||||
private string _r2path = "";
|
||||
private string _rasm2path = "";
|
||||
public int memsize = 1024;
|
||||
public int maxprogsize = 64;
|
||||
private IR2Pipe r2 = null;
|
||||
private int nPlayers = 0;
|
||||
public int uidx = 0;
|
||||
public List<player> players = new List<player>();
|
||||
public enum eArch
|
||||
{
|
||||
mips32,
|
||||
mips64,
|
||||
arm16,
|
||||
arm32,
|
||||
arm64,
|
||||
gb,
|
||||
x86,
|
||||
x64
|
||||
}
|
||||
private eArch _arch = eArch.x86;
|
||||
public string arch
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_arch == eArch.arm16)
|
||||
return "arm 16 bits";
|
||||
if (_arch == eArch.arm32)
|
||||
return "arm 32 bits";
|
||||
if (_arch == eArch.arm64)
|
||||
return "arm 64 bits";
|
||||
if (_arch == eArch.mips32)
|
||||
return "mips 32 bits";
|
||||
if (_arch == eArch.mips64)
|
||||
return "mips 64bits";
|
||||
if (_arch == eArch.gb)
|
||||
return "gb 16 bits";
|
||||
if (_arch == eArch.x64)
|
||||
return "x86 64 bits";
|
||||
return "x86 32 bits";
|
||||
}
|
||||
}
|
||||
public string r2path
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
if (_r2path == "")
|
||||
{
|
||||
string ruta = "";
|
||||
if (!OperatingSystem.IsWindows())
|
||||
ruta = "r2";
|
||||
else
|
||||
ruta = "radare2.exe";
|
||||
return ruta;
|
||||
}
|
||||
return this._r2path;
|
||||
|
||||
}
|
||||
set
|
||||
{
|
||||
this._r2path = value;
|
||||
}
|
||||
}
|
||||
public string rasm2path
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
if (_rasm2path == "")
|
||||
{
|
||||
string ruta = "";
|
||||
if (!OperatingSystem.IsWindows())
|
||||
ruta = "rasm2";
|
||||
else
|
||||
ruta = "rasm2.exe";
|
||||
return ruta;
|
||||
}
|
||||
else
|
||||
return this._rasm2path;
|
||||
|
||||
}
|
||||
set
|
||||
{
|
||||
this._rasm2path = value;
|
||||
}
|
||||
}
|
||||
public string runcommand(string cmd)
|
||||
{
|
||||
return this.r2.RunCommand(cmd).Replace("\r", "");
|
||||
}
|
||||
public string RunAndGetOutput(string program, string arguments)
|
||||
{
|
||||
System.Diagnostics.Process p = new System.Diagnostics.Process();
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
p.StartInfo.FileName = program;
|
||||
p.StartInfo.Arguments = arguments;
|
||||
p.Start();
|
||||
string output = p.StandardOutput.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
return output;
|
||||
}
|
||||
|
||||
List<int> get_random_offsets(int nRandoms)
|
||||
{
|
||||
System.Random rnd = new System.Random();
|
||||
List<int> rand = new List<int>();
|
||||
int addr = rnd.Next(0, this.memsize - this.maxprogsize);
|
||||
if (addr % 4 != 0)
|
||||
addr -= addr % 4;
|
||||
rand.Add(addr);
|
||||
int ini = addr;
|
||||
int fin = addr + maxprogsize;
|
||||
while (true)
|
||||
{
|
||||
addr = rnd.Next(0, this.memsize - this.maxprogsize);
|
||||
if (addr % 4 != 0)
|
||||
addr -= addr % 4;
|
||||
if ((addr < ini && addr + maxprogsize < ini) || (addr > fin))
|
||||
{
|
||||
rand.Add(addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rand;
|
||||
}
|
||||
string initstate = "";
|
||||
public string Init(string[] files, string[] usernames, eArch arch)
|
||||
{
|
||||
players.Clear();
|
||||
initstate = "";
|
||||
Console.WriteLine("r2path = " + r2path);
|
||||
if (File.Exists(r2path) || !OperatingSystem.IsWindows())
|
||||
{
|
||||
List<int> offsets;
|
||||
int idx = 0;
|
||||
string file = "";
|
||||
string strname = "";
|
||||
string cone = string.Format("-w malloc://{0}", this.memsize);
|
||||
if (this.r2 == null)
|
||||
this.r2 = new R2Pipe(cone, r2path);
|
||||
// el primer comando enviado no parece funcionar luego todo va bien.
|
||||
this.r2.RunCommand("pd");
|
||||
//
|
||||
string rasm2param = "";
|
||||
if (arch == eArch.mips32)
|
||||
{
|
||||
_arch = eArch.mips32;
|
||||
this.r2.RunCommand("e asm.arch=mips");
|
||||
this.r2.RunCommand("e asm.bits=32");
|
||||
rasm2param = "-a mips -b 32";
|
||||
}
|
||||
else if (arch == eArch.mips64)
|
||||
{
|
||||
_arch = eArch.mips32;
|
||||
this.r2.RunCommand("e asm.arch=mips");
|
||||
this.r2.RunCommand("e asm.bits=64");
|
||||
rasm2param = "-a mips -b 64";
|
||||
}
|
||||
else if (arch == eArch.arm64)
|
||||
{
|
||||
_arch = eArch.mips32;
|
||||
this.r2.RunCommand("e asm.arch=arm");
|
||||
this.r2.RunCommand("e asm.bits=64");
|
||||
rasm2param = "-a mips -b 64";
|
||||
}
|
||||
else if (arch == eArch.arm32)
|
||||
{
|
||||
_arch = eArch.arm32;
|
||||
this.r2.RunCommand("e asm.arch=arm");
|
||||
this.r2.RunCommand("e asm.bits=32");
|
||||
rasm2param = "-a arm -b 32";
|
||||
}
|
||||
else if (arch == eArch.arm16)
|
||||
{
|
||||
_arch = eArch.arm16;
|
||||
this.r2.RunCommand("e asm.arch=arm");
|
||||
this.r2.RunCommand("e asm.bits=16");
|
||||
rasm2param = "-a arm -b 16";
|
||||
}
|
||||
else if (arch == eArch.gb)
|
||||
{
|
||||
_arch = eArch.gb;
|
||||
this.r2.RunCommand("e asm.arch=gb");
|
||||
this.r2.RunCommand("e asm.bits=16");
|
||||
rasm2param = "-a gb -b 16";
|
||||
}
|
||||
else if (arch == eArch.x64)
|
||||
{
|
||||
_arch = eArch.x64;
|
||||
this.r2.RunCommand("e asm.arch=x86");
|
||||
this.r2.RunCommand("e asm.bits=64");
|
||||
rasm2param = "-a x86 -b 64";
|
||||
}
|
||||
else
|
||||
{
|
||||
_arch = eArch.x86;
|
||||
this.r2.RunCommand("e asm.arch=x86");
|
||||
this.r2.RunCommand("e asm.bits=32");
|
||||
rasm2param = "-a x86 -b 32";
|
||||
}
|
||||
this.r2.RunCommand("e scr.color=false");
|
||||
this.r2.RunCommand("e asm.lines=false");
|
||||
this.r2.RunCommand("e asm.flags=false");
|
||||
this.r2.RunCommand("e asm.comments=false");
|
||||
this.r2.RunCommand("aei");
|
||||
|
||||
if (initstate == "")
|
||||
{
|
||||
this.r2.RunCommand("aeim");
|
||||
|
||||
initstate = this.r2.RunCommand("aerR").Replace("\r", "").Replace("\n", ";");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.r2.RunCommand(initstate);
|
||||
}
|
||||
|
||||
this.r2.RunCommand(string.Format("w0 {0} @ 0", memsize));
|
||||
|
||||
nPlayers = files.Count();
|
||||
offsets = get_random_offsets(this.nPlayers);
|
||||
for (int x = 0; x < this.nPlayers; x++)
|
||||
{
|
||||
file = files[x];
|
||||
int addr = offsets[idx];
|
||||
idx++;
|
||||
string src = RunAndGetOutput(rasm2path, string.Format("{0} -f {1}", rasm2param, file)).Replace("\r", "").Replace("\n", "");
|
||||
if (src == "")
|
||||
{
|
||||
return "Invalid source";
|
||||
}
|
||||
Console.WriteLine("Rasm Output = " + src);
|
||||
// Añadimos el codigo a radare2
|
||||
string cmd = string.Format("wx {0} @ {1}", src, addr);
|
||||
this.r2.RunCommand(cmd);
|
||||
cmd = string.Format("aer PC={0}", addr);
|
||||
this.r2.RunCommand(cmd);
|
||||
cmd = string.Format("aer SP=SP+{0}", addr);
|
||||
this.r2.RunCommand(cmd);
|
||||
|
||||
string initRegs = this.r2.RunCommand("aerR").Replace("\r", "").Replace("\n", ";");
|
||||
// generamos el jugador
|
||||
strname = usernames[x];
|
||||
int ciclos = GetPCInstructionCycles(x);
|
||||
// Iniciamos el jugador añadiendo sus datos de programa, ciclos
|
||||
player p = new player(strname, addr, src.Length / 2, src, initRegs, ciclos);
|
||||
// lo añadimos a la lista de jugadores
|
||||
players.Add(p);
|
||||
|
||||
players[x].actual.ins = GetPCInstruction(x);
|
||||
players[x].actual.dasm = GetFullProgram(x);
|
||||
players[x].actual.regs = GetRegs(x);
|
||||
players[x].actual.pc = "0x" + GetPC(x).ToString("X8");
|
||||
players[x].actual.mem = GetMemAccessRAW(x);
|
||||
// borramos el log
|
||||
p.log.Clear();
|
||||
|
||||
|
||||
}
|
||||
if (players.Count < 2)
|
||||
{
|
||||
return "You need at least 2 users";
|
||||
}
|
||||
this.r2.RunCommand("e cmd.esil.todo=f theend=1");
|
||||
this.r2.RunCommand("e cmd.esil.trap=f theend=1");
|
||||
this.r2.RunCommand("e cmd.esil.intr=f theend=1");
|
||||
this.r2.RunCommand("e cmd.esil.ioer=f theend=1");
|
||||
this.r2.RunCommand("f theend=0");
|
||||
this.r2.RunCommand(string.Format("b {0}", memsize));
|
||||
return "OK";
|
||||
}
|
||||
return "NOK";
|
||||
}
|
||||
|
||||
public bool ReiniciaGame(bool bNew)
|
||||
{
|
||||
List<int> offsets = get_random_offsets(this.nPlayers);
|
||||
string cmd = "";
|
||||
this.r2.RunCommand(string.Format("w0 {0} @ 0", memsize));
|
||||
for (int x = 0; x < this.nPlayers; x++)
|
||||
{
|
||||
this.r2.RunCommand(players[x].userini);
|
||||
players[x].user = players[x].userini;
|
||||
if (bNew)
|
||||
{
|
||||
// ponemos la nueva direccion
|
||||
players[x].orig = offsets[x];
|
||||
// restauramos el contexto inicial
|
||||
this.r2.RunCommand(players[x].user);
|
||||
// ponemos el nuevo PC
|
||||
cmd = string.Format("aer PC={0}", offsets[x]);
|
||||
this.r2.RunCommand(cmd);
|
||||
// obtenemos los registros
|
||||
string initRegs = this.r2.RunCommand("aerR").Replace("\r", "").Replace("\n", ";");
|
||||
// actualizamos los registros iniciales del usuario
|
||||
players[x].user = initRegs;
|
||||
players[x].userini = initRegs;
|
||||
}
|
||||
else
|
||||
{
|
||||
// restauramos el contexto inicial
|
||||
this.r2.RunCommand(players[x].user);
|
||||
}
|
||||
cmd = string.Format("wx {0} @ {1}", players[x].code, players[x].orig);
|
||||
this.r2.RunCommand(cmd);
|
||||
// Actualizamos la informacion del PC actual
|
||||
players[x].actual.ins = GetPCInstruction();
|
||||
players[x].actual.dasm = GetFullProgram();
|
||||
players[x].actual.regs = GetRegs();
|
||||
players[x].actual.pc = "0x" + GetPC().ToString("X8");
|
||||
players[x].actual.mem = GetMemAccessRAW();
|
||||
// borramos el log
|
||||
players[x].log.Clear();
|
||||
}
|
||||
|
||||
this.r2.RunCommand("f theend=0");
|
||||
return true;
|
||||
}
|
||||
public bool checkDead()
|
||||
{
|
||||
string te = this.r2.RunCommand("?v 1+theend").Replace("\r", "").Replace("\n", "");
|
||||
if (te != "" && te != "0x1")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void switchUser()
|
||||
{
|
||||
uidx++;
|
||||
if (uidx >= players.Count)
|
||||
uidx = 0;
|
||||
this.r2.RunCommand(players[this.uidx].user);
|
||||
}
|
||||
public void switchUser(int nuser)
|
||||
{
|
||||
if (nuser >= 0 && nuser < players.Count)
|
||||
{
|
||||
this.r2.RunCommand(players[nuser].user);
|
||||
uidx = nuser;
|
||||
}
|
||||
}
|
||||
public int thisplayer
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.uidx;
|
||||
}
|
||||
}
|
||||
|
||||
public int otherplayer
|
||||
{
|
||||
get
|
||||
{
|
||||
int o = this.uidx + 1;
|
||||
if (o >= players.Count)
|
||||
o = 0;
|
||||
return o;
|
||||
}
|
||||
}
|
||||
public void switchUserIdx()
|
||||
{
|
||||
uidx++;
|
||||
if (uidx >= players.Count)
|
||||
uidx = 0;
|
||||
}
|
||||
public void switchUserIdx(int nuser)
|
||||
{
|
||||
if (nuser >= 0 && nuser < players.Count)
|
||||
{
|
||||
uidx = nuser;
|
||||
}
|
||||
}
|
||||
|
||||
public bool cyleszero()
|
||||
{
|
||||
|
||||
if (players[this.uidx].cycles == 0)
|
||||
{
|
||||
players[this.uidx].cycles = -1;
|
||||
return true;
|
||||
}
|
||||
players[this.uidx].cycles--;
|
||||
return false;
|
||||
}
|
||||
public int stepIn()
|
||||
{
|
||||
this.r2.RunCommand("aes");
|
||||
players[this.uidx].user = this.r2.RunCommand("aerR").Replace("\r", "").Replace("\n", ";");
|
||||
players[this.uidx].cycles = GetPCInstructionCycles();
|
||||
return GetPC(this.uidx);
|
||||
}
|
||||
|
||||
public void stepIn(int nuser)
|
||||
{
|
||||
switchUser(nuser);
|
||||
stepIn();
|
||||
}
|
||||
public int GetPC()
|
||||
{
|
||||
string tmp = this.r2.RunCommand("aer PC");
|
||||
string tmp1 = tmp.Substring(3).Replace("\r", "").Replace("\n", "");
|
||||
int res = Convert.ToInt32(tmp1, 16);
|
||||
return res;
|
||||
}
|
||||
public int GetPC(int nuser)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetPC();
|
||||
}
|
||||
public string GetPCInstruction()
|
||||
{
|
||||
string a = this.r2.RunCommand("o");
|
||||
string b = this.r2.RunCommand("s PC;pd 1").Replace("\r", "");
|
||||
return b.Replace("\n","");
|
||||
}
|
||||
public string GetPCInstruction(int nuser)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetPCInstruction();
|
||||
}
|
||||
|
||||
public int GetPCInstructionCycles(int nuser)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetPCInstructionCycles();
|
||||
}
|
||||
public int GetPCInstructionCycles()
|
||||
{
|
||||
int result = 0;
|
||||
string json = this.r2.RunCommand("s PC; aoj 1").Replace("\r", "");
|
||||
int ini = json.IndexOf("cycles");
|
||||
if (ini > 0)
|
||||
{
|
||||
string tmp = json.Substring(ini + 8, json.IndexOf(",", ini + 8) - (ini + 8));
|
||||
int.TryParse(tmp, out result);
|
||||
if (result < 0) result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public string GetRegs(string format = "")
|
||||
{
|
||||
return this.r2.RunCommand("aer" + format).Replace("\r", "");
|
||||
}
|
||||
public string GetRegs(int nuser)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetRegs();
|
||||
}
|
||||
public string GetPCProgram()
|
||||
{
|
||||
string query = string.Format("s PC; pd 8");
|
||||
string tmp = this.r2.RunCommand(query);
|
||||
return tmp.Replace("\r", "");
|
||||
}
|
||||
public string GetPCProgram(int nuser)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetPCProgram();
|
||||
}
|
||||
|
||||
public string GetFullProgram()
|
||||
{
|
||||
string query = string.Format("pD {0} @ {1}", players[this.uidx].size, players[this.uidx].orig);
|
||||
string tmp = this.r2.RunCommand(query);
|
||||
return tmp.Replace("\r", "");
|
||||
}
|
||||
public string GetFullProgram(int nuser)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetFullProgram();
|
||||
}
|
||||
|
||||
public string GetMemAccessRAW()
|
||||
{
|
||||
return this.r2.RunCommand("s PC;aea*").Replace("\r", "");
|
||||
}
|
||||
public string GetMemAccessRAW(int nuser)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetMemAccessRAW();
|
||||
}
|
||||
public Dictionary<int, int> GetMemAccessReadDict(string memaccess)
|
||||
{
|
||||
string[] ls = memaccess.Split('\n');
|
||||
int address = 0;
|
||||
int size = 0;
|
||||
Dictionary<int, int> dicMemRead = new Dictionary<int, int>();
|
||||
foreach (string s in ls)
|
||||
{
|
||||
if (s.StartsWith("f mem.read."))
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] l = s.Substring(s.IndexOf("0x")).Replace(" ", "").Split('@');
|
||||
size = Convert.ToInt32(l[0].Substring(2), 16);
|
||||
address = Convert.ToInt32(l[1].Substring(2), 16);
|
||||
dicMemRead.Add(address, size);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return dicMemRead;
|
||||
}
|
||||
public int GetMemAccessRead(string memaccess)
|
||||
{
|
||||
Dictionary<int, int> dicMemRead = GetMemAccessReadDict(memaccess);
|
||||
if (dicMemRead.Count > 0)
|
||||
{
|
||||
foreach (var a in dicMemRead)
|
||||
{
|
||||
if (a.Key >= 0 && a.Key <= memsize)
|
||||
return a.Key;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public int GetMemAccessRead(int nuser, string memaccess)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetMemAccessRead(memaccess);
|
||||
}
|
||||
|
||||
public Dictionary<int, int> GetMemAccessWriteDict(string memaccess)
|
||||
{
|
||||
string[] ls = memaccess.Split('\n');
|
||||
int address = 0;
|
||||
int size = 0;
|
||||
Dictionary<int, int> dicMemWrite = new Dictionary<int, int>();
|
||||
foreach (string s in ls)
|
||||
{
|
||||
if (s.StartsWith("f mem.write."))
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] l = s.Substring(s.IndexOf("0x")).Replace(" ", "").Split('@');
|
||||
size = Convert.ToInt32(l[0].Substring(2), 16);
|
||||
address = Convert.ToInt32(l[1].Substring(2), 16);
|
||||
dicMemWrite.Add(address, size);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return dicMemWrite;
|
||||
}
|
||||
public int GetMemAccessWrite(string memaccess)
|
||||
{
|
||||
Dictionary<int, int> dicMemWrite = GetMemAccessWriteDict(memaccess);
|
||||
if (dicMemWrite.Count > 0)
|
||||
{
|
||||
foreach (var a in dicMemWrite)
|
||||
{
|
||||
if (a.Key >= 0 && a.Key <= memsize)
|
||||
return a.Key;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public int GetMemAccessWrite(int nuser, string memaccess)
|
||||
{
|
||||
switchUser(nuser);
|
||||
return GetMemAccessWrite(memaccess);
|
||||
}
|
||||
|
||||
public string GetUserName()
|
||||
{
|
||||
return players[uidx].name;
|
||||
}
|
||||
public string GetUserName(int nuser)
|
||||
{
|
||||
if (players.Count > 0)
|
||||
return players[nuser].name;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public int GetAddressProgram()
|
||||
{
|
||||
return players[uidx].orig;
|
||||
}
|
||||
public int GetAddressProgram(int nuser)
|
||||
{
|
||||
return players[nuser].orig;
|
||||
}
|
||||
|
||||
public int GetSizeProgram()
|
||||
{
|
||||
return players[uidx].size;
|
||||
}
|
||||
public int GetSizeProgram(int nuser)
|
||||
{
|
||||
return players[nuser].size;
|
||||
}
|
||||
public int GetCycles()
|
||||
{
|
||||
return players[uidx].cycles;
|
||||
}
|
||||
public int GetCycles(int nuser)
|
||||
{
|
||||
return players[nuser].cycles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public bool stepInfoNew(string txtmemoria)
|
||||
{
|
||||
// Obtenemos los indices del jugador actual y el otro
|
||||
int thisplayer = uidx;
|
||||
int otherplayer = uidx + 1;
|
||||
if (otherplayer >= players.Count)
|
||||
otherplayer = 0;
|
||||
|
||||
string res = this.r2.RunCommand(players[thisplayer].user + ";s PC;aea*;aes;aerR;s PC;aoj 1;aer PC;?v 1+theend").Replace("\r", "");
|
||||
string[] lines = res.Split('\n');
|
||||
string[] regs = lines.Where(i => i.StartsWith("aer")).ToArray();
|
||||
string[] memaccess = lines.Where(i => i.StartsWith("f")).ToArray();
|
||||
string[] json = lines.Where(i => i.StartsWith("[")).ToArray();
|
||||
string[] PC = lines.Where(i => i.StartsWith("0x")).ToArray();
|
||||
|
||||
string userregs = string.Join(";", regs);
|
||||
string regs1 = string.Join("\n", regs).Replace("aer ", "");
|
||||
string mem = string.Join("\n", memaccess);
|
||||
string j = json[0];
|
||||
int ini = j.IndexOf("cycles");
|
||||
int ciclos = 0;
|
||||
if (ini > 0)
|
||||
{
|
||||
string tmp = j.Substring(ini + 8, j.IndexOf(",", ini + 8) - (ini + 8));
|
||||
int.TryParse(tmp, out ciclos);
|
||||
if (ciclos < 0) ciclos = 0;
|
||||
}
|
||||
|
||||
// Generamos la peticion de desensamblado del PC actual del jugador actual
|
||||
int pc = Convert.ToInt32(PC[0].Substring(3), 16);
|
||||
string query = "";
|
||||
if (pc < players[thisplayer].orig || pc >= players[thisplayer].orig + players[thisplayer].size)
|
||||
query = string.Format("s PC; pd 8");
|
||||
else
|
||||
query = string.Format("pD {0} @ {1}", players[thisplayer].size, players[thisplayer].orig);
|
||||
|
||||
|
||||
int otherpc = players[otherplayer].actual.ipc();
|
||||
Dictionary<int, int> dicMemWrite = GetMemAccessWriteDict(mem);
|
||||
bool bThisPCAltered = false;
|
||||
bool bOtherPCAltered = false;
|
||||
|
||||
if (dicMemWrite.Count > 0)
|
||||
{
|
||||
foreach (var i in dicMemWrite)
|
||||
{
|
||||
if (i.Key >= 0 && i.Key <= memsize)
|
||||
{
|
||||
for (int x = 0; x < i.Value; x++)
|
||||
{
|
||||
if (i.Key + x == otherpc)
|
||||
{
|
||||
bOtherPCAltered = true;
|
||||
}
|
||||
if (i.Key + x == pc)
|
||||
{
|
||||
bThisPCAltered = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generamos la peticion de desensamblado del PC del otro jugador
|
||||
string otherquery = "";
|
||||
if (otherpc < players[otherplayer].orig || otherpc >= players[otherplayer].orig + players[otherplayer].size)
|
||||
otherquery = string.Format("s {0}; pd 8", players[otherplayer].actual.pc);
|
||||
else
|
||||
otherquery = string.Format("pD {0} @ {1}", players[otherplayer].size, players[otherplayer].orig);
|
||||
|
||||
// Procesamos el output de radare y obtenemos los 2 desensamblados
|
||||
string bothdasm = this.r2.RunCommand(query + ";?e split;" + otherquery).Replace("\r", "");
|
||||
string[] tmpdasm = bothdasm.Split(new string[] { "split" }, StringSplitOptions.None);
|
||||
string dasm = tmpdasm[0];
|
||||
string otherdasm = tmpdasm[1];
|
||||
|
||||
int x1 = dasm.IndexOf(PC[0]);
|
||||
string newins = dasm.Substring(x1, dasm.IndexOf('\n', x1) - x1);
|
||||
|
||||
|
||||
if (PC[1] != "" && PC[1] != "0x1")
|
||||
players[thisplayer].actual.dead = true;
|
||||
else
|
||||
players[thisplayer].actual.dead = false;
|
||||
|
||||
// si han cambiado los desensamblados del otro jugador, actualizamos y añadimos una linea de log con el nuevo.
|
||||
if (bOtherPCAltered)
|
||||
{
|
||||
players[otherplayer].actual.dasm = otherdasm;
|
||||
}
|
||||
//
|
||||
// si han cambiado los desensamblados del jugador actual, actualizamos y añadimos una linea de log con el nuevo.
|
||||
if (bThisPCAltered)
|
||||
{
|
||||
players[thisplayer].actual.dasm = dasm;
|
||||
}
|
||||
|
||||
// Añadimos al log la instruccion que se ejecuto
|
||||
players[thisplayer].logAdd(new clsinfo(players[thisplayer].actual.pc, players[thisplayer].actual.ins, players[thisplayer].actual.dasm, players[thisplayer].actual.regs, players[thisplayer].actual.mem, players[thisplayer].cycles+1, txtmemoria));
|
||||
|
||||
|
||||
// Actualizamos los ciclos y registros
|
||||
players[this.uidx].user = userregs;
|
||||
|
||||
if (players[this.uidx].cycles == -1)
|
||||
players[this.uidx].cyclesfixed = ciclos;
|
||||
|
||||
players[this.uidx].cycles = ciclos;
|
||||
|
||||
|
||||
// Actualizamos la instruccion actual
|
||||
players[thisplayer].actual.pc = PC[0];
|
||||
players[thisplayer].actual.ins = newins;
|
||||
players[thisplayer].actual.mem = mem;
|
||||
players[thisplayer].actual.dasm = dasm;
|
||||
players[thisplayer].actual.regs = regs1;
|
||||
|
||||
|
||||
return players[thisplayer].actual.dead;
|
||||
}
|
||||
|
||||
public string formatregs(string regs)
|
||||
{
|
||||
string[] reg = regs.Split('\n');
|
||||
string regformat = "";
|
||||
int x = 0;
|
||||
foreach (string s in reg)
|
||||
{
|
||||
if (s.StartsWith("oeax") == false)
|
||||
{
|
||||
if (x % 3 == 0 && x != 0)
|
||||
regformat += "\n";
|
||||
regformat += s + " ";
|
||||
x++;
|
||||
}
|
||||
}
|
||||
return regformat;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
services:
|
||||
r2wars:
|
||||
image: r2wars:latest
|
||||
build: .
|
||||
volumes:
|
||||
- ./warriors:/r2wars/warriors:ro
|
||||
expose:
|
||||
- 9664
|
||||
ports:
|
||||
- 127.0.0.1:9966:9966
|
||||
init: true
|
||||
tty: true
|
||||
container_name: r2wars
|
||||
|
||||
web:
|
||||
image: nginx:alpine
|
||||
depends_on:
|
||||
- r2wars
|
||||
ports:
|
||||
- 127.0.0.1:9664:80
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
@@ -0,0 +1,28 @@
|
||||
VERSION=$(shell ../version.sh)
|
||||
R2W=r2wars-$(VERSION)
|
||||
DOTNET?=dotnet
|
||||
|
||||
all:
|
||||
$(DOTNET) build r2wars.sln
|
||||
|
||||
run:
|
||||
$(DOTNET) run --project r2wars.csproj -- ../warriors
|
||||
|
||||
ls:
|
||||
$(SHELL) lsbots.sh
|
||||
|
||||
dist:
|
||||
rm -rf $(R2W)
|
||||
$(DOTNET) publish r2wars.csproj --configuration Release --output $(R2W) --no-self-contained
|
||||
cp -f ../RELEASE_README.md $(R2W)/README.txt
|
||||
mkdir -p $(R2W)/warriors
|
||||
cp -rf ../examples/. $(R2W)/warriors
|
||||
zip -r $(R2W).zip $(R2W)
|
||||
rm -rf $(R2W)
|
||||
|
||||
r2w32:
|
||||
wget -c http://radare.mikelloc.com/get/2.7.0/radare2_installer-msvc_64-2.7.0.exe
|
||||
|
||||
clean:
|
||||
$(DOTNET) clean r2wars.sln
|
||||
rm -rf bin obj r2wars-*.zip
|
||||
@@ -4,6 +4,11 @@ public class MyEvent : EventArgs
|
||||
{
|
||||
public string message;
|
||||
public int ganador;
|
||||
public int perdedor;
|
||||
public string winnername;
|
||||
public string losername;
|
||||
public string loserreason;
|
||||
public string loserins;
|
||||
public int round;
|
||||
public int ciclos;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net.WebSockets;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
static public class r2warsStatic
|
||||
{
|
||||
static public r2wars r2w = new r2wars();
|
||||
static public Torneo torneo = new Torneo();
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
string listenAddress = OperatingSystem.IsWindows() ? "127.0.0.1" : "0.0.0.0";
|
||||
string httpUrl = Environment.GetEnvironmentVariable("R2WARS_HTTP_URL") ??
|
||||
"http://" + listenAddress + ":9664";
|
||||
string websocketUrl = Environment.GetEnvironmentVariable("R2WARS_WEBSOCKET_URL") ??
|
||||
"http://" + listenAddress + ":9966";
|
||||
|
||||
if (args.Length > 0)
|
||||
r2warsStatic.torneo.SetWarriorsDirectory(args[0]);
|
||||
|
||||
WebApplicationBuilder builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions
|
||||
{
|
||||
ContentRootPath = AppContext.BaseDirectory,
|
||||
WebRootPath = Path.Combine(AppContext.BaseDirectory, "wwwroot")
|
||||
});
|
||||
builder.WebHost.UseKestrel();
|
||||
builder.WebHost.UseUrls(httpUrl, websocketUrl);
|
||||
builder.Services.AddRouting();
|
||||
|
||||
WebApplication app = builder.Build();
|
||||
app.UseWebSockets();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.Map("/r2wars", async context =>
|
||||
{
|
||||
if (!context.WebSockets.IsWebSocketRequest)
|
||||
{
|
||||
context.Response.StatusCode = StatusCodes.Status400BadRequest;
|
||||
await context.Response.WriteAsync("A WebSocket connection is required.");
|
||||
return;
|
||||
}
|
||||
|
||||
using WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
|
||||
await r2warsWebSocket.HandleAsync(socket, context.RequestAborted);
|
||||
});
|
||||
|
||||
app.MapFallbackToFile("index.html");
|
||||
|
||||
Console.WriteLine("Web server running at " + httpUrl);
|
||||
Console.WriteLine("WebSocket server running at " + websocketUrl.Replace("http://", "ws://") + "/r2wars");
|
||||
Console.WriteLine("Press Ctrl-C to stop r2wars.");
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(httpUrl)
|
||||
{
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
|
||||
await app.RunAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,598 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
public class Torneo
|
||||
{
|
||||
static readonly List<TournamentTeam> teams = new List<TournamentTeam>();
|
||||
static readonly List<TournamentRound> rounds = new List<TournamentRound>();
|
||||
static readonly Dictionary<long, string> teamNames = new Dictionary<long, string>();
|
||||
static readonly Dictionary<long, string> teamWarriors = new Dictionary<long, string>();
|
||||
static r2wars r2w;
|
||||
|
||||
readonly object lifecycleLock = new object();
|
||||
readonly object stateLock = new object();
|
||||
readonly List<TournamentPairing> allcombats = new List<TournamentPairing>();
|
||||
readonly TournamentTeamScore[] actualcombatscore = { null, null };
|
||||
readonly string[] actualcombatnames = { "", "" };
|
||||
readonly string[] actualcombatwarriors = { "", "" };
|
||||
|
||||
RoundRobinPairingsGenerator generator;
|
||||
Task tournamentTask;
|
||||
string[] loadedWarriors = new string[0];
|
||||
string loadedArchitecture = "mixed";
|
||||
string loadedExtension = ".asm";
|
||||
string fullCombatLog = "";
|
||||
string actualCombatLog = "";
|
||||
string actualDeadReason = "";
|
||||
string warriorsDirectory = "warriors";
|
||||
string browserWarriorsDirectory = "";
|
||||
string workflow = "idle";
|
||||
string workflowMessage = "Load warriors to begin.";
|
||||
string scores = "No tournament loaded.";
|
||||
int ncombat;
|
||||
volatile bool tournamentActive;
|
||||
volatile bool tournamentAutoRun;
|
||||
public volatile bool bCombatEnd = true;
|
||||
|
||||
public Torneo()
|
||||
{
|
||||
r2w = r2warsStatic.r2w;
|
||||
r2w.Event_combatEnd += new MyHandler1(CombatEnd);
|
||||
r2w.Event_roundEnd += new MyHandler1(RoundEnd);
|
||||
r2w.Event_roundExhausted += new MyHandler1(RoundExhausted);
|
||||
AppDomain.CurrentDomain.ProcessExit += (sender, eventArgs) => CleanupBrowserWarriors();
|
||||
}
|
||||
|
||||
public void SetWarriorsDirectory(string wd)
|
||||
{
|
||||
warriorsDirectory = wd;
|
||||
}
|
||||
|
||||
void SendDrawEvent(string value)
|
||||
{
|
||||
r2w.send_draw_event(value);
|
||||
}
|
||||
|
||||
void SetWorkflow(string value, string message)
|
||||
{
|
||||
lock (stateLock)
|
||||
{
|
||||
workflow = value;
|
||||
workflowMessage = message;
|
||||
}
|
||||
}
|
||||
|
||||
string BuildStateJson(string console, string summary)
|
||||
{
|
||||
lock (stateLock)
|
||||
{
|
||||
StringBuilder json = new StringBuilder();
|
||||
json.Append("{\"workflow\":").Append(JsonUtil.Quote(workflow));
|
||||
json.Append(",\"message\":").Append(JsonUtil.Quote(workflowMessage));
|
||||
json.Append(",\"status\":").Append(JsonUtil.Quote(workflowMessage));
|
||||
json.Append(",\"scores\":").Append(JsonUtil.Quote(scores));
|
||||
json.Append(",\"completedCombats\":").Append(ncombat);
|
||||
json.Append(",\"totalCombats\":").Append(allcombats.Count);
|
||||
if (console != null)
|
||||
json.Append(",\"console\":").Append(JsonUtil.Quote(console));
|
||||
if (summary != null)
|
||||
json.Append(",\"summary\":").Append(JsonUtil.Quote(summary));
|
||||
json.Append("}");
|
||||
return json.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetStateJson()
|
||||
{
|
||||
return BuildStateJson(null, null);
|
||||
}
|
||||
|
||||
void SendState(string console = null, string summary = null)
|
||||
{
|
||||
SendDrawEvent(BuildStateJson(console, summary));
|
||||
}
|
||||
|
||||
string BuildScores()
|
||||
{
|
||||
if (generator == null || teams.Count < 2)
|
||||
return "No scores yet.";
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.Append("STANDINGS — ").Append(ncombat).Append(" / ").Append(allcombats.Count).Append(" battles complete\n\n");
|
||||
result.Append("RANK WARRIOR RESULTS\n");
|
||||
result.Append("---- ---------------------------- -----------------------------------------\n");
|
||||
try
|
||||
{
|
||||
foreach (TournamentRanking standing in generator.GenerateRankings())
|
||||
{
|
||||
string name = teamNames[standing.Team.TeamId];
|
||||
if (name.Length > 28)
|
||||
name = name.Substring(0, 25) + "...";
|
||||
result.Append(standing.Rank.ToString().PadLeft(4)).Append(" ");
|
||||
result.Append(name.PadRight(28)).Append(" ");
|
||||
result.Append(standing.ScoreDescription).Append("\n");
|
||||
}
|
||||
}
|
||||
catch (InvalidTournamentStateException)
|
||||
{
|
||||
result.Append("Standings are being initialized.\n");
|
||||
}
|
||||
return result.ToString().TrimEnd();
|
||||
}
|
||||
|
||||
private void RoundEnd(object sender, MyEvent e)
|
||||
{
|
||||
if (!tournamentActive)
|
||||
return;
|
||||
int round = e.round + 1;
|
||||
string roundResult = " Round " + round + ": " + e.winnername + " wins (" + e.ciclos + " cycles)\n" +
|
||||
" Defeat reason: " + e.loserreason + "\n" +
|
||||
" Instruction: " + e.loserins + "\n";
|
||||
fullCombatLog += roundResult;
|
||||
actualCombatLog += roundResult;
|
||||
actualDeadReason += "Round " + round + " winner: " + e.winnername + "\n" +
|
||||
" Defeated: " + e.losername + "\n" +
|
||||
" Reason: " + e.loserreason + "\n" +
|
||||
" Instruction: " + e.loserins + "\n\n";
|
||||
|
||||
if (e.ganador >= 0 && e.ganador < actualcombatscore.Length && actualcombatscore[e.ganador] != null)
|
||||
actualcombatscore[e.ganador].Score += new HighestPointsScore(1);
|
||||
|
||||
scores = BuildScores();
|
||||
SendState(actualCombatLog);
|
||||
}
|
||||
|
||||
private void RoundExhausted(object sender, MyEvent e)
|
||||
{
|
||||
if (!tournamentActive)
|
||||
return;
|
||||
int round = e.round + 1;
|
||||
string timeout = " Round " + round + ": timeout (" + e.ciclos + " cycles)\n";
|
||||
actualCombatLog += timeout;
|
||||
fullCombatLog += timeout;
|
||||
actualDeadReason += timeout;
|
||||
SendState(actualCombatLog);
|
||||
}
|
||||
|
||||
private void CombatEnd(object sender, MyEvent e)
|
||||
{
|
||||
if (!tournamentActive)
|
||||
return;
|
||||
actualCombatLog += "Battle winner: " + e.winnername + "\n";
|
||||
fullCombatLog += "Battle winner: " + e.winnername + "\n";
|
||||
actualDeadReason += "Winner: " + e.winnername + "\n";
|
||||
ncombat++;
|
||||
bCombatEnd = true;
|
||||
scores = BuildScores();
|
||||
|
||||
if (ncombat >= allcombats.Count)
|
||||
{
|
||||
FinishTournament();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tournamentAutoRun || r2w.bStopAtRoundStart)
|
||||
{
|
||||
tournamentAutoRun = false;
|
||||
SetWorkflow("paused", "Battle complete. Resume for the next battle, or Step through it one cycle at a time.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWorkflow("running", "Battle complete. Starting the next battle…");
|
||||
}
|
||||
SendState(actualCombatLog, actualDeadReason);
|
||||
}
|
||||
|
||||
bool PrepareNextCombat(bool autoStart)
|
||||
{
|
||||
lock (lifecycleLock)
|
||||
{
|
||||
if (!tournamentActive || !bCombatEnd || ncombat >= allcombats.Count)
|
||||
return false;
|
||||
|
||||
int player = 0;
|
||||
foreach (TournamentTeamScore teamScore in allcombats[ncombat].TeamScores)
|
||||
{
|
||||
actualcombatnames[player] = teamNames[teamScore.Team.TeamId];
|
||||
actualcombatwarriors[player] = teamWarriors[teamScore.Team.TeamId];
|
||||
actualcombatscore[player] = teamScore;
|
||||
actualcombatscore[player].Score += new HighestPointsScore(0);
|
||||
player++;
|
||||
}
|
||||
|
||||
actualCombatLog = "Battle " + (ncombat + 1) + " / " + allcombats.Count + ": " +
|
||||
actualcombatnames[0] + " vs " + actualcombatnames[1] + "\n";
|
||||
actualDeadReason = actualcombatnames[0] + " vs " + actualcombatnames[1] + "\n\n";
|
||||
fullCombatLog += actualCombatLog;
|
||||
bCombatEnd = false;
|
||||
|
||||
if (autoStart)
|
||||
SetWorkflow("running", "Battle " + (ncombat + 1) + " / " + allcombats.Count + " is running.");
|
||||
else
|
||||
SetWorkflow("paused", "Battle " + (ncombat + 1) + " / " + allcombats.Count + " is ready. Step advances one cycle; Resume runs continuously.");
|
||||
SendState(actualCombatLog);
|
||||
|
||||
bool initialized = r2w.playcombat(
|
||||
actualcombatwarriors[0], actualcombatwarriors[1],
|
||||
actualcombatnames[0], actualcombatnames[1], false, autoStart);
|
||||
if (!initialized)
|
||||
{
|
||||
bCombatEnd = true;
|
||||
tournamentAutoRun = false;
|
||||
SetWorkflow("paused", "The battle could not be initialized. Check the warrior files, then reload them.");
|
||||
SendState();
|
||||
}
|
||||
return initialized;
|
||||
}
|
||||
}
|
||||
|
||||
void FinishTournament()
|
||||
{
|
||||
lock (lifecycleLock)
|
||||
{
|
||||
if (workflow == "finished")
|
||||
return;
|
||||
tournamentAutoRun = false;
|
||||
tournamentActive = false;
|
||||
bCombatEnd = true;
|
||||
fullCombatLog += "Tournament finished " + DateTime.Now + "\n";
|
||||
scores = BuildScores();
|
||||
SetWorkflow("finished", "Tournament complete. Review the final standings or choose Play again to reset all scores.");
|
||||
SendState(fullCombatLog, scores + "\n\nLAST BATTLE\n\n" + actualDeadReason);
|
||||
SaveTournamentReport();
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTournamentReport()
|
||||
{
|
||||
try
|
||||
{
|
||||
string filename = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".r2wars.txt";
|
||||
using (StreamWriter writer = File.CreateText(filename))
|
||||
{
|
||||
writer.WriteLine(scores);
|
||||
writer.WriteLine();
|
||||
writer.WriteLine("FULL LOG");
|
||||
writer.WriteLine("========");
|
||||
writer.Write(fullCombatLog);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.Error.WriteLine("Could not save tournament report: " + exception.Message);
|
||||
}
|
||||
}
|
||||
|
||||
void TournamentLoop()
|
||||
{
|
||||
while (tournamentActive)
|
||||
{
|
||||
if (tournamentAutoRun && bCombatEnd)
|
||||
PrepareNextCombat(true);
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
bool BeginTournament()
|
||||
{
|
||||
if (allcombats.Count == 0 || loadedWarriors.Length < 2)
|
||||
{
|
||||
SetWorkflow("idle", "At least two warriors must be loaded before starting a tournament.");
|
||||
SendState();
|
||||
return false;
|
||||
}
|
||||
if (workflow == "finished")
|
||||
{
|
||||
SetWorkflow("finished", "This tournament is complete. Choose Play again to reset the scores first.");
|
||||
SendState();
|
||||
return false;
|
||||
}
|
||||
if (tournamentActive)
|
||||
return true;
|
||||
|
||||
fullCombatLog = "Tournament started " + DateTime.Now + "\n";
|
||||
tournamentActive = true;
|
||||
bCombatEnd = true;
|
||||
tournamentTask = Task.Factory.StartNew(TournamentLoop);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void StopTournament()
|
||||
{
|
||||
tournamentAutoRun = false;
|
||||
tournamentActive = false;
|
||||
lock (lifecycleLock)
|
||||
{
|
||||
r2w.CancelCombat();
|
||||
bCombatEnd = true;
|
||||
}
|
||||
Task task = tournamentTask;
|
||||
if (task != null && !task.IsCompleted)
|
||||
task.Wait(2000);
|
||||
}
|
||||
|
||||
public string getemptymemory()
|
||||
{
|
||||
StringBuilder memory = new StringBuilder();
|
||||
for (int index = 0; index < 1024; index++)
|
||||
{
|
||||
if (index > 0)
|
||||
memory.Append(',');
|
||||
memory.Append("\"\"");
|
||||
}
|
||||
return memory.ToString();
|
||||
}
|
||||
|
||||
private void CreatePairings(string[] selectedfiles, string architecture, string extension)
|
||||
{
|
||||
r2w.ClearHistory();
|
||||
allcombats.Clear();
|
||||
teamNames.Clear();
|
||||
teamWarriors.Clear();
|
||||
rounds.Clear();
|
||||
teams.Clear();
|
||||
ncombat = 0;
|
||||
fullCombatLog = "";
|
||||
actualCombatLog = "";
|
||||
actualDeadReason = "";
|
||||
loadedWarriors = (string[])selectedfiles.Clone();
|
||||
loadedArchitecture = architecture;
|
||||
loadedExtension = extension;
|
||||
generator = new RoundRobinPairingsGenerator();
|
||||
generator.Reset();
|
||||
|
||||
for (int index = 0; index < selectedfiles.Length; index++)
|
||||
{
|
||||
TournamentTeam team = new TournamentTeam(index, 0);
|
||||
teams.Add(team);
|
||||
string filename = Path.GetFileName(selectedfiles[index]);
|
||||
string name = filename.EndsWith(extension, StringComparison.OrdinalIgnoreCase)
|
||||
? filename.Substring(0, filename.Length - extension.Length)
|
||||
: filename;
|
||||
teamNames.Add(index, name);
|
||||
teamWarriors.Add(index, selectedfiles[index]);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
generator.Reset();
|
||||
generator.LoadState(teams, rounds);
|
||||
TournamentRound round = generator.CreateNextRound(null);
|
||||
if (round == null)
|
||||
break;
|
||||
rounds.Add(round);
|
||||
}
|
||||
foreach (TournamentRound round in rounds)
|
||||
foreach (TournamentPairing pairing in round.Pairings)
|
||||
allcombats.Add(pairing);
|
||||
|
||||
string console = "Tournament architecture: " + architecture + "\n" +
|
||||
"Warriors directory: " + warriorsDirectory + "\n" +
|
||||
"Loaded warriors (" + selectedfiles.Length + "):";
|
||||
foreach (string warrior in selectedfiles)
|
||||
console += "\n • " + Path.GetFileName(warrior);
|
||||
|
||||
if (selectedfiles.Length < 2)
|
||||
{
|
||||
scores = "No tournament loaded.";
|
||||
SetWorkflow("idle", "At least two .asm warriors are required. Add warriors, then load again.");
|
||||
console += "\n\nAt least two warriors are required to start a tournament.";
|
||||
}
|
||||
else
|
||||
{
|
||||
scores = BuildScores();
|
||||
SetWorkflow("ready", selectedfiles.Length + " warriors loaded for " + allcombats.Count + " battles. Start the tournament when ready.");
|
||||
console += "\n\nReady for " + allcombats.Count + " round-robin battles.";
|
||||
}
|
||||
|
||||
string resetDisplay = "{\"player1\":{\"regs\":\"\",\"code\":\"\",\"name\":\"Player 1\"}," +
|
||||
"\"player2\":{\"regs\":\"\",\"code\":\"\",\"name\":\"Player 2\"}," +
|
||||
"\"memory\":[" + getemptymemory() + "],\"activePlayer\":-1," +
|
||||
"\"historyPosition\":0,\"historyCount\":0,\"canBrowseEarlier\":false,\"canBrowseLater\":false}";
|
||||
SendDrawEvent(resetDisplay);
|
||||
SendState(console);
|
||||
}
|
||||
|
||||
public void LoadTournamentPlayers()
|
||||
{
|
||||
StopTournament();
|
||||
CleanupBrowserWarriors();
|
||||
string[] files;
|
||||
try
|
||||
{
|
||||
files = Directory.GetFiles(warriorsDirectory)
|
||||
.Where(path => path.EndsWith(".asm", StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(path => path, StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
loadedWarriors = new string[0];
|
||||
scores = "No tournament loaded.";
|
||||
SetWorkflow("idle", "The warriors directory could not be read: " + exception.Message);
|
||||
SendDrawEvent("nowarriors");
|
||||
SendState();
|
||||
return;
|
||||
}
|
||||
CreatePairings(files, "mixed (detected from each filename)", ".asm");
|
||||
}
|
||||
|
||||
public List<BrowserWarriorSource> GetWarriorSources()
|
||||
{
|
||||
string[] files = loadedWarriors.Where(File.Exists).ToArray();
|
||||
if (files.Length == 0)
|
||||
{
|
||||
if (!Directory.Exists(warriorsDirectory))
|
||||
return new List<BrowserWarriorSource>();
|
||||
files = Directory.GetFiles(warriorsDirectory)
|
||||
.Where(path => path.EndsWith(".asm", StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(path => path, StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
}
|
||||
return files.Select(path => new BrowserWarriorSource
|
||||
{
|
||||
Name = Path.GetFileName(path),
|
||||
Source = File.ReadAllText(path)
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public void LoadTournamentSources(IReadOnlyList<BrowserWarriorSource> warriors)
|
||||
{
|
||||
if (warriors == null)
|
||||
throw new ArgumentNullException(nameof(warriors));
|
||||
if (warriors.Count > 128)
|
||||
throw new InvalidOperationException("A tournament cannot contain more than 128 bots.");
|
||||
|
||||
HashSet<string> names = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (BrowserWarriorSource warrior in warriors)
|
||||
{
|
||||
string name = (warrior?.Name ?? "").Trim();
|
||||
if (name.Length == 0 || name != Path.GetFileName(name) || name.Contains('/') || name.Contains('\\') ||
|
||||
name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
|
||||
throw new InvalidOperationException("Bot filenames must not contain a directory path.");
|
||||
if (!name.EndsWith(".asm", StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException(name + ": filename must end in .asm");
|
||||
if (WarriorCompiler.ArchitectureFromName(name) == r2archs.eArch.unknown)
|
||||
throw new InvalidOperationException(name + ": architecture must be encoded in the filename");
|
||||
if (!names.Add(name))
|
||||
throw new InvalidOperationException("Duplicate bot filename: " + name);
|
||||
if (string.IsNullOrWhiteSpace(warrior.Source))
|
||||
throw new InvalidOperationException(name + ": source is empty");
|
||||
}
|
||||
|
||||
StopTournament();
|
||||
string directory = Path.Combine(Path.GetTempPath(), "r2wars-web-" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(directory);
|
||||
try
|
||||
{
|
||||
string[] files = warriors
|
||||
.OrderBy(warrior => warrior.Name, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(warrior =>
|
||||
{
|
||||
string path = Path.Combine(directory, warrior.Name.Trim());
|
||||
File.WriteAllText(path, warrior.Source);
|
||||
return path;
|
||||
}).ToArray();
|
||||
CleanupBrowserWarriors();
|
||||
browserWarriorsDirectory = directory;
|
||||
CreatePairings(files, "mixed (browser sources)", ".asm");
|
||||
}
|
||||
catch
|
||||
{
|
||||
try { Directory.Delete(directory, true); }
|
||||
catch (IOException) { }
|
||||
catch (UnauthorizedAccessException) { }
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanupBrowserWarriors()
|
||||
{
|
||||
if (string.IsNullOrEmpty(browserWarriorsDirectory))
|
||||
return;
|
||||
string directory = browserWarriorsDirectory;
|
||||
browserWarriorsDirectory = "";
|
||||
try { Directory.Delete(directory, true); }
|
||||
catch (IOException) { }
|
||||
catch (UnauthorizedAccessException) { }
|
||||
}
|
||||
|
||||
public void ResetTournament()
|
||||
{
|
||||
StopTournament();
|
||||
if (loadedWarriors.Length < 2)
|
||||
{
|
||||
LoadTournamentPlayers();
|
||||
return;
|
||||
}
|
||||
CreatePairings(loadedWarriors, loadedArchitecture, loadedExtension);
|
||||
}
|
||||
|
||||
public void StopActualCombat()
|
||||
{
|
||||
if (workflow != "running")
|
||||
return;
|
||||
tournamentAutoRun = false;
|
||||
lock (lifecycleLock)
|
||||
r2w.StopCombate();
|
||||
if (workflow != "finished")
|
||||
{
|
||||
SetWorkflow("paused", "Paused. Resume continuous play or Step exactly one cycle.");
|
||||
SendState();
|
||||
}
|
||||
}
|
||||
|
||||
public void StepTournamentCombats()
|
||||
{
|
||||
if (workflow != "paused")
|
||||
return;
|
||||
if (!BeginTournament())
|
||||
return;
|
||||
|
||||
tournamentAutoRun = false;
|
||||
if (bCombatEnd && !PrepareNextCombat(false))
|
||||
return;
|
||||
if (!r2w.bThreadIni && r2w.bInCombat)
|
||||
r2w.stepCombate();
|
||||
if (workflow != "finished")
|
||||
{
|
||||
SetWorkflow("paused", "Paused after one cycle. Step again or Resume continuous play.");
|
||||
SendState();
|
||||
}
|
||||
}
|
||||
|
||||
public void RunTournamentCombats()
|
||||
{
|
||||
if (workflow != "ready" && workflow != "paused")
|
||||
return;
|
||||
if (!BeginTournament())
|
||||
return;
|
||||
|
||||
tournamentAutoRun = true;
|
||||
SetWorkflow("running", "Tournament running. Pause at any time to inspect or step.");
|
||||
SendState();
|
||||
if (!bCombatEnd && r2w.bInCombat && !r2w.bThreadIni)
|
||||
r2w.iniciaCombate();
|
||||
}
|
||||
}
|
||||
|
||||
internal static class JsonUtil
|
||||
{
|
||||
public static string Quote(string value)
|
||||
{
|
||||
if (value == null)
|
||||
return "null";
|
||||
StringBuilder result = new StringBuilder(value.Length + 2);
|
||||
result.Append('"');
|
||||
foreach (char character in value)
|
||||
{
|
||||
switch (character)
|
||||
{
|
||||
case '"': result.Append("\\\""); break;
|
||||
case '\\': result.Append("\\\\"); break;
|
||||
case '\b': result.Append("\\b"); break;
|
||||
case '\f': result.Append("\\f"); break;
|
||||
case '\n': result.Append("\\n"); break;
|
||||
case '\r': result.Append("\\r"); break;
|
||||
case '\t': result.Append("\\t"); break;
|
||||
default:
|
||||
if (character < 32)
|
||||
result.Append("\\u").Append(((int)character).ToString("x4"));
|
||||
else
|
||||
result.Append(character);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.Append('"');
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
-13
@@ -3,7 +3,6 @@
|
||||
/// <summary>
|
||||
/// Thrown when an IPairingsGenerator is asked to load a state that does not represent a valid tournament within its constraints.
|
||||
/// </summary>
|
||||
[global::System.Serializable]
|
||||
public class InvalidTournamentStateException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
@@ -32,16 +31,4 @@
|
||||
: base(message, inner)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the InvalidTournamentStateException class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="info">The System.Runtime.Serialization.SerializationInfo that holds the serialized object data about the exception being thrown.</param>
|
||||
/// <param name="context">The System.Runtime.Serialization.StreamingContext that contains contextual information about the source or destination.</param>
|
||||
/// <exception cref="System.ArgumentNullException">The info parameter is null.</exception>
|
||||
/// <exception cref="System.Runtime.Serialization.SerializationException">The class name is null or System.Exception.HResult is zero (0).</exception>
|
||||
protected InvalidTournamentStateException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -386,11 +386,11 @@
|
||||
lastRecord = rank.Record;
|
||||
lastRank = rank.Rank;
|
||||
|
||||
string scoreDescription = String.Format("{0:F} ({1}-{2}-{3} with {4} overall).", rank.Record.WinRecord, rank.Record.Wins, rank.Record.Draws, rank.Record.Losses, rank.Record.OverallScore);
|
||||
string roundWins = rank.Record.OverallScore == null ? "0" : rank.Record.OverallScore.ToString();
|
||||
string scoreDescription = String.Format("{0:0.0} match pts · {1}W {2}D {3}L · {4} round wins", rank.Record.WinRecord, rank.Record.Wins, rank.Record.Draws, rank.Record.Losses, roundWins);
|
||||
yield return new TournamentRanking(rank.Team, rank.Rank, scoreDescription);
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
public sealed class BrowserWarriorSource
|
||||
{
|
||||
public string Name { get; set; } = "";
|
||||
public string Source { get; set; } = "";
|
||||
}
|
||||
|
||||
public sealed class WarriorAssemblyResult
|
||||
{
|
||||
public bool Ok { get; set; }
|
||||
public byte[] Bytes { get; set; } = Array.Empty<byte>();
|
||||
public int Size { get { return Bytes.Length; } }
|
||||
public string Message { get; set; } = "";
|
||||
}
|
||||
|
||||
public static class WarriorCompiler
|
||||
{
|
||||
public const int MaximumWarriorSize = 512;
|
||||
|
||||
public static r2archs.eArch ArchitectureFromName(string name)
|
||||
{
|
||||
return r2archs.archfromfileext((name ?? "").ToLowerInvariant());
|
||||
}
|
||||
|
||||
public static WarriorAssemblyResult Assemble(BrowserWarriorSource warrior)
|
||||
{
|
||||
if (warrior == null)
|
||||
return Failure("No bot source was provided.");
|
||||
|
||||
r2archs.eArch architecture = ArchitectureFromName(warrior.Name);
|
||||
if (architecture == r2archs.eArch.unknown)
|
||||
return Failure((warrior.Name ?? "Unnamed bot") + ": architecture must be encoded in the filename");
|
||||
if (string.IsNullOrWhiteSpace(warrior.Source))
|
||||
return Failure((warrior.Name ?? "Unnamed bot") + ": source is empty");
|
||||
if (warrior.Source.Length > 64 * 1024)
|
||||
return Failure((warrior.Name ?? "Unnamed bot") + ": source is too large to preview");
|
||||
|
||||
string temporaryFile = Path.Combine(Path.GetTempPath(), "r2wars-assemble-" + Guid.NewGuid().ToString("N") + ".asm");
|
||||
try
|
||||
{
|
||||
File.WriteAllText(temporaryFile, warrior.Source);
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = r2paths.rasm2,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true
|
||||
};
|
||||
foreach (string argument in r2archs.rasm2param(architecture).Split(' ', StringSplitOptions.RemoveEmptyEntries))
|
||||
startInfo.ArgumentList.Add(argument);
|
||||
startInfo.ArgumentList.Add("-f");
|
||||
startInfo.ArgumentList.Add(temporaryFile);
|
||||
|
||||
using Process process = Process.Start(startInfo);
|
||||
if (process == null)
|
||||
return Failure("rasm2 could not be started.");
|
||||
Task<string> stdoutTask = process.StandardOutput.ReadToEndAsync();
|
||||
Task<string> stderrTask = process.StandardError.ReadToEndAsync();
|
||||
process.WaitForExit();
|
||||
string stdout = stdoutTask.GetAwaiter().GetResult();
|
||||
string stderr = stderrTask.GetAwaiter().GetResult().Trim();
|
||||
string hex = new string(stdout.Where(character => !char.IsWhiteSpace(character)).ToArray());
|
||||
|
||||
if (process.ExitCode != 0 || hex.Length == 0 || hex.Length % 2 != 0 || !hex.All(Uri.IsHexDigit))
|
||||
return Failure(stderr.Length > 0 ? stderr : "rasm2 could not assemble this bot.");
|
||||
|
||||
byte[] bytes = new byte[hex.Length / 2];
|
||||
for (int index = 0; index < bytes.Length; index++)
|
||||
bytes[index] = Convert.ToByte(hex.Substring(index * 2, 2), 16);
|
||||
bool oversized = bytes.Length > MaximumWarriorSize;
|
||||
return new WarriorAssemblyResult
|
||||
{
|
||||
Ok = !oversized,
|
||||
Bytes = bytes,
|
||||
Message = oversized
|
||||
? "Compiles, but exceeds the " + MaximumWarriorSize + "-byte warrior limit."
|
||||
: "Compiles successfully."
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
return Failure(exception.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { File.Delete(temporaryFile); }
|
||||
catch (IOException) { }
|
||||
catch (UnauthorizedAccessException) { }
|
||||
}
|
||||
}
|
||||
|
||||
private static WarriorAssemblyResult Failure(string message)
|
||||
{
|
||||
return new WarriorAssemblyResult { Ok = false, Message = message };
|
||||
}
|
||||
}
|
||||
}
|
||||
+1095
File diff suppressed because it is too large.
Load diff
@@ -68,6 +68,7 @@ public class R2Pipe : IR2Pipe, System.IDisposable
|
||||
|
||||
r2Process.Start();
|
||||
r2Process.StandardInput.AutoFlush = true;
|
||||
r2Process.StandardInput.NewLine = "\n";
|
||||
// ignore first run
|
||||
r2Process.StandardOutput.Read();
|
||||
// Console.WriteLine(r2Process.StandardOutput.Read());
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../examples
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
(
|
||||
for a in warriors/* ; do
|
||||
if [ "`echo $a | grep txt$`" ]; then
|
||||
continue;
|
||||
fi
|
||||
printf "$a "
|
||||
if [ "`echo $a | grep x86-32`" ]; then
|
||||
rasm2 -a x86 -b 32 -f $a |wc -c
|
||||
elif [ "`echo $a | grep arm-64`" ]; then
|
||||
rasm2 -a arm -b 64 -f $a |wc -c
|
||||
elif [ "`echo $a | grep arm-16`" ]; then
|
||||
rasm2 -a arm -b 16 -f $a |wc -c
|
||||
elif [ "`echo $a | grep mips-32`" ]; then
|
||||
rasm2 -a mips -b 32 -f $a |wc -c
|
||||
elif [ "`echo $a | grep 8051`" ]; then
|
||||
rasm2 -a 8051 -f $a |wc -c
|
||||
fi
|
||||
done
|
||||
) |awk '{print $2"\t"$1}'
|
||||
@@ -0,0 +1,749 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
public class r2wars
|
||||
{
|
||||
private const int MAX_CYCLES = 2000;
|
||||
private const int MAX_HISTORY_STATES = 2048;
|
||||
private sealed class UiHistoryEntry
|
||||
{
|
||||
public string Regs1;
|
||||
public string Code1;
|
||||
public string Regs2;
|
||||
public string Code2;
|
||||
public string Memory;
|
||||
public string Status;
|
||||
public int ActivePlayer;
|
||||
}
|
||||
|
||||
public clsEngine Engine = null;
|
||||
public bool bThreadIni = false;
|
||||
public bool bStopProcess = false;
|
||||
public bool bInCombat = false;
|
||||
public bool sync_var = false;
|
||||
public bool bStopAtRoundEnd = false;
|
||||
public bool bStopAtRoundStart = false;
|
||||
public event MyHandler1 Event_draw;
|
||||
public event MyHandler1 Event_roundEnd;
|
||||
public event MyHandler1 Event_combatEnd;
|
||||
public event MyHandler1 Event_roundExhausted;
|
||||
public string answer = "";
|
||||
string[] pColor = { "b", "r" };
|
||||
string[] cRead = { "q", "y" };
|
||||
string[] cWrite = { "v", "o" };
|
||||
string[] rr = { "", "" };
|
||||
string[] dd = { "", "" };
|
||||
string[] memoria = new string[1024];
|
||||
readonly object historyLock = new object();
|
||||
readonly List<UiHistoryEntry> uiHistory = new List<UiHistoryEntry>();
|
||||
int historyIndex = -1;
|
||||
string status = "Idle";
|
||||
int[] victorias = { 0, 0 };
|
||||
int totalciclos = 0;
|
||||
int nRound = 0;
|
||||
public int nExausted = 0;
|
||||
bool bDead = false;
|
||||
bool bSingleRound = false;
|
||||
Task gameLoopTask = null;
|
||||
public r2wars()
|
||||
{
|
||||
if (Engine == null)
|
||||
Engine = new clsEngine();
|
||||
initmemoria();
|
||||
}
|
||||
public void send_draw_event(string s)
|
||||
{
|
||||
// this pause is magic
|
||||
// Firefox can free memory
|
||||
// chrome never consume memory and work smooth on drawing
|
||||
Thread.Sleep(5);
|
||||
MyEvent e1 = new MyEvent();
|
||||
e1.message = s;
|
||||
if (Event_draw != null)
|
||||
{
|
||||
Event_draw(0, e1);
|
||||
/*
|
||||
Task t = Task.Factory.StartNew(() =>
|
||||
{
|
||||
while (!sync_var)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
});
|
||||
t.Wait();
|
||||
*/
|
||||
}
|
||||
e1 = null;
|
||||
}
|
||||
string json_output(UiHistoryEntry historyEntry = null)
|
||||
{
|
||||
string username1 = Engine.GetUserName(0);
|
||||
string username2 = Engine.GetUserName(1);
|
||||
string regs1;
|
||||
string code1;
|
||||
string regs2;
|
||||
string code2;
|
||||
string memory;
|
||||
string outputStatus;
|
||||
int activePlayer;
|
||||
int historyPosition;
|
||||
int historyCount;
|
||||
bool canBrowseEarlier;
|
||||
bool canBrowseLater;
|
||||
|
||||
if (historyEntry == null)
|
||||
{
|
||||
lock (rr)
|
||||
{
|
||||
regs1 = rr[0];
|
||||
regs2 = rr[1];
|
||||
}
|
||||
lock (dd)
|
||||
{
|
||||
code1 = dd[0];
|
||||
code2 = dd[1];
|
||||
}
|
||||
memory = getmemoria();
|
||||
outputStatus = status;
|
||||
activePlayer = Engine != null && bInCombat ? Engine.thisplayer : -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
regs1 = historyEntry.Regs1;
|
||||
code1 = historyEntry.Code1;
|
||||
regs2 = historyEntry.Regs2;
|
||||
code2 = historyEntry.Code2;
|
||||
memory = historyEntry.Memory;
|
||||
outputStatus = historyEntry.Status;
|
||||
activePlayer = historyEntry.ActivePlayer;
|
||||
}
|
||||
|
||||
lock (historyLock)
|
||||
{
|
||||
historyCount = uiHistory.Count;
|
||||
historyPosition = historyIndex >= 0 ? historyIndex + 1 : 0;
|
||||
canBrowseEarlier = historyIndex > 0;
|
||||
canBrowseLater = historyIndex >= 0 && historyIndex < uiHistory.Count - 1;
|
||||
}
|
||||
if (historyEntry != null)
|
||||
{
|
||||
string location = historyPosition == historyCount ? "Latest state" :
|
||||
"History " + historyPosition + " / " + historyCount;
|
||||
outputStatus = location + " — " + outputStatus;
|
||||
}
|
||||
|
||||
string salida = "{\"player1\":{\"regs\":" + JsonUtil.Quote(regs1) + ",\"code\":" + JsonUtil.Quote(code1) + ",\"name\":" + JsonUtil.Quote(username1) + "}," +
|
||||
"\"player2\":{\"regs\":" + JsonUtil.Quote(regs2) + ",\"code\":" + JsonUtil.Quote(code2) + ",\"name\":" + JsonUtil.Quote(username2) + "}," +
|
||||
"\"memory\":[" + memory + "],\"status\":" + JsonUtil.Quote(outputStatus) + ",\"activePlayer\":" + activePlayer.ToString() +
|
||||
",\"historyPosition\":" + historyPosition.ToString() + ",\"historyCount\":" + historyCount.ToString() +
|
||||
",\"canBrowseEarlier\":" + (canBrowseEarlier ? "true" : "false") +
|
||||
",\"canBrowseLater\":" + (canBrowseLater ? "true" : "false") + "}";
|
||||
return salida;
|
||||
}
|
||||
private void PublishCurrentState()
|
||||
{
|
||||
UiHistoryEntry entry = new UiHistoryEntry();
|
||||
lock (rr)
|
||||
{
|
||||
entry.Regs1 = rr[0];
|
||||
entry.Regs2 = rr[1];
|
||||
}
|
||||
lock (dd)
|
||||
{
|
||||
entry.Code1 = dd[0];
|
||||
entry.Code2 = dd[1];
|
||||
}
|
||||
entry.Memory = getmemoria();
|
||||
entry.Status = status;
|
||||
entry.ActivePlayer = Engine != null && bInCombat ? Engine.thisplayer : -1;
|
||||
lock (historyLock)
|
||||
{
|
||||
uiHistory.Add(entry);
|
||||
if (uiHistory.Count > MAX_HISTORY_STATES)
|
||||
uiHistory.RemoveAt(0);
|
||||
historyIndex = uiHistory.Count - 1;
|
||||
}
|
||||
send_draw_event(json_output());
|
||||
}
|
||||
public void ClearHistory()
|
||||
{
|
||||
lock (historyLock)
|
||||
{
|
||||
uiHistory.Clear();
|
||||
historyIndex = -1;
|
||||
}
|
||||
}
|
||||
public void initmemoria()
|
||||
{
|
||||
for (int x = 0; x < 1024; x++)
|
||||
memoria[x] = "\"\"";
|
||||
}
|
||||
public string getmemoria()
|
||||
{
|
||||
lock (memoria)
|
||||
{
|
||||
string salida = "";
|
||||
for (int x = 0; x < 1024; x++)
|
||||
salida += memoria[x] + ",";
|
||||
return salida.Remove(salida.Length - 1);
|
||||
}
|
||||
|
||||
}
|
||||
void pinta(long offset, string c, string s)
|
||||
{
|
||||
lock (memoria)
|
||||
{
|
||||
if (offset>=0 && offset<Engine.memsize)
|
||||
memoria[offset] = "\"" + c + s + "\"";
|
||||
}
|
||||
}
|
||||
void pinta(long offset, string c,string s,int count)
|
||||
{
|
||||
lock (memoria)
|
||||
{
|
||||
while ((count--) != 0)
|
||||
if (offset >= 0 && offset < 1024)
|
||||
memoria[offset++] = "\"" + c + s + "\"";
|
||||
//else
|
||||
// Console.WriteLine("Zascaaaaa");
|
||||
}
|
||||
}
|
||||
public void testpinta()
|
||||
{
|
||||
initmemoria();
|
||||
pinta(1023, "F");
|
||||
pinta(0, "F");
|
||||
|
||||
PublishCurrentState();
|
||||
|
||||
}
|
||||
void pinta(int offset, string c)
|
||||
{
|
||||
lock (memoria)
|
||||
{
|
||||
if (offset >= 0 && offset < Engine.memsize)
|
||||
memoria[offset] = "\"" + c + "\"";
|
||||
}
|
||||
}
|
||||
void pinta(int offset, int count, string c)
|
||||
{
|
||||
lock (memoria)
|
||||
{
|
||||
while ((count--) != 0)
|
||||
if (offset >= 0 && offset < 1024)
|
||||
memoria[offset++] = "\"" + c + "\"";
|
||||
//else
|
||||
// Console.WriteLine("Zascaaaaa");
|
||||
}
|
||||
}
|
||||
void drawplayerturn(int nplayer)
|
||||
{
|
||||
}
|
||||
string padlines(string t,int maxlen=54)
|
||||
{
|
||||
string b = "";
|
||||
string[] lineas = t.Split('\n');
|
||||
foreach (string l in lineas)
|
||||
{
|
||||
if (l.Length > maxlen)
|
||||
b += l.Substring(0, maxlen) + "\n";
|
||||
else
|
||||
{
|
||||
string pad = "";
|
||||
for (int n = 0; n < maxlen - l.Length; n++)
|
||||
pad += " ";
|
||||
b += l + pad + "\n";
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
void drawPC(int nplayer)
|
||||
{
|
||||
long oldPC = Engine.players[nplayer].actual.oldpc;
|
||||
if (oldPC >= 0 && oldPC <= Engine.memsize)
|
||||
{
|
||||
pinta(oldPC, pColor[nplayer], "", Engine.players[nplayer].actual.oldpcsize);
|
||||
}
|
||||
long aPC = Engine.players[nplayer].actual.ipc();
|
||||
// ponemos la X en la posicion nueva
|
||||
if (aPC >= 0 && aPC <= Engine.memsize)
|
||||
{
|
||||
pinta(aPC, pColor[nplayer], "X", Engine.players[nplayer].actual.pcsize);
|
||||
}
|
||||
}
|
||||
void drawscreen(int nplayer)
|
||||
{
|
||||
// seleccionamos el offset actual y lo pintamos invertido
|
||||
string dasm = padlines(Engine.players[nplayer].actual.dasm);
|
||||
string actual = padlines(Engine.players[nplayer].actual.ins);
|
||||
int i = dasm.IndexOf(actual);
|
||||
if (i != -1)
|
||||
{
|
||||
dasm = dasm.Insert(i + actual.Length, "</span>");
|
||||
dasm = dasm.Insert(i, "<span class='s'>");
|
||||
}
|
||||
|
||||
lock (dd)
|
||||
{
|
||||
dd[nplayer] = "Cycles:" + Engine.players[nplayer].actual.cycles.ToString() + "\nActual Instruction:\n " + padlines(Engine.players[nplayer].actual.ins.Substring(16)) + "\n" + dasm;
|
||||
}
|
||||
lock (rr)
|
||||
{
|
||||
rr[nplayer] = Engine.players[nplayer].actual.formatregs();
|
||||
}
|
||||
|
||||
}
|
||||
void drawmemaccess(int nplayer)
|
||||
{
|
||||
Dictionary<int, int> dicMemRead = Engine.GetMemAccessReadDict(Engine.players[nplayer].actual.mem);
|
||||
Dictionary<int, int> dicMemWrite = Engine.GetMemAccessWriteDict(Engine.players[nplayer].actual.mem);
|
||||
if (dicMemRead.Count > 0)
|
||||
{
|
||||
foreach (var i in dicMemRead)
|
||||
{
|
||||
if (i.Key >= 0 && i.Key <= Engine.memsize)
|
||||
{
|
||||
for (int x = 0; x < i.Value; x++)
|
||||
pinta(i.Key + x, cRead[nplayer],"R");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dicMemWrite.Count > 0)
|
||||
{
|
||||
foreach (var i in dicMemWrite)
|
||||
{
|
||||
if (i.Key >= 0 && i.Key <= Engine.memsize)
|
||||
{
|
||||
for (int x = 0; x < i.Value; x++)
|
||||
{
|
||||
pinta(i.Key + x, cWrite[nplayer],"W");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void resetTablero()
|
||||
{
|
||||
initmemoria();
|
||||
pinta(Engine.GetAddressProgram(0), Engine.GetSizeProgram(0), "b");
|
||||
pinta(Engine.GetAddressProgram(1), Engine.GetSizeProgram(1), "r");
|
||||
}
|
||||
private void update(int n)
|
||||
{
|
||||
|
||||
if (bDead)
|
||||
{
|
||||
drawplayerturn(Engine.thisplayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Dibujamos la info del jugador
|
||||
drawscreen(Engine.thisplayer);
|
||||
drawPC(Engine.thisplayer);
|
||||
// dibujamos la info del nuevo jugador
|
||||
drawscreen(Engine.otherplayer);
|
||||
drawPC(Engine.otherplayer);
|
||||
// ponemos el marco del jugador actual
|
||||
drawplayerturn(Engine.otherplayer);
|
||||
// Dibujamos los accesos a memoria
|
||||
drawmemaccess(Engine.thisplayer);
|
||||
}
|
||||
PublishCurrentState();
|
||||
}
|
||||
private void RoundExhausted()
|
||||
{
|
||||
Debug.WriteLine("RoundExhausted::Invoked.");
|
||||
// Actualizamos la pantalla indicando que pinte los programas
|
||||
if (Event_roundExhausted != null)
|
||||
{
|
||||
MyEvent e3 = new MyEvent();
|
||||
e3.message = "";
|
||||
e3.ganador = 0;
|
||||
e3.round = nRound;
|
||||
e3.ciclos = totalciclos;
|
||||
e3.winnername = "";
|
||||
Event_roundExhausted(this, e3);
|
||||
}
|
||||
|
||||
}
|
||||
private void RoundEnd()
|
||||
{
|
||||
// notificamos fin del round
|
||||
Debug.WriteLine("RoundEnd::Invoked.");
|
||||
if (Event_roundEnd != null)
|
||||
{
|
||||
MyEvent e2 = new MyEvent();
|
||||
e2.message = "";
|
||||
e2.ganador = Engine.thisplayer;
|
||||
e2.round = nRound;
|
||||
e2.ciclos = totalciclos;
|
||||
e2.winnername = Engine.players[Engine.thisplayer].name;
|
||||
|
||||
e2.loserins = Engine.players[Engine.otherplayer].actual.deadins;
|
||||
e2.loserreason = Engine.players[Engine.otherplayer].actual.deadinfo;
|
||||
e2.losername = Engine.players[Engine.otherplayer].name;
|
||||
|
||||
|
||||
Event_roundEnd(this, e2);
|
||||
}
|
||||
|
||||
}
|
||||
private void CombatEnd(bool empate=false)
|
||||
{
|
||||
Debug.WriteLine("CombatEnd::Invoked.");
|
||||
status = "Battle complete";
|
||||
if (Event_combatEnd != null)
|
||||
{
|
||||
MyEvent e1 = new MyEvent();
|
||||
e1.message = "";
|
||||
if (victorias[0] > victorias[1])
|
||||
{
|
||||
e1.ganador = 0;
|
||||
e1.perdedor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
e1.ganador = 1;
|
||||
e1.perdedor = 0;
|
||||
}
|
||||
|
||||
e1.round = nRound;
|
||||
e1.ciclos = totalciclos;
|
||||
if (!empate)
|
||||
{
|
||||
e1.winnername = Engine.players[e1.ganador].name;
|
||||
}
|
||||
else
|
||||
e1.winnername = "Draw";
|
||||
this.Event_combatEnd(this, e1);
|
||||
}
|
||||
}
|
||||
|
||||
private void espera(int veces, int pausa = 1)
|
||||
{
|
||||
Task t = Task.Factory.StartNew(() =>
|
||||
{
|
||||
int n = veces;
|
||||
while ((n--) > 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(pausa);
|
||||
}
|
||||
});
|
||||
t.Wait();
|
||||
}
|
||||
private void ExecuteRoundInstruction(bool bWait)
|
||||
{
|
||||
if (Engine.cyleszero())
|
||||
{
|
||||
// Realizamos el STEP
|
||||
bDead = Engine.stepInfoNew(getmemoria());
|
||||
//update(1);
|
||||
if (bDead)
|
||||
{
|
||||
Console.WriteLine("dead");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dibujamos la info del jugador
|
||||
drawPC(Engine.thisplayer);
|
||||
// dibujamos la info del nuevo jugador
|
||||
drawPC(Engine.otherplayer);
|
||||
// Dibujamos los accesos a memoria
|
||||
drawmemaccess(Engine.thisplayer);
|
||||
drawplayerturn(Engine.otherplayer);
|
||||
drawscreen(Engine.thisplayer);
|
||||
drawscreen(Engine.otherplayer);
|
||||
PublishCurrentState();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//Engine.players[Engine.thisplayer].logAdd(new clsinfo(Engine.players[Engine.thisplayer].actual.pc, Engine.players[Engine.thisplayer].actual.ins, Engine.players[Engine.thisplayer].actual.dasm, Engine.players[Engine.thisplayer].actual.regs, Engine.players[Engine.thisplayer].actual.mem, Engine.players[Engine.thisplayer].actual.cycles + 1, getmemoria()));
|
||||
drawplayerturn(Engine.otherplayer);
|
||||
drawscreen(Engine.thisplayer);
|
||||
drawscreen(Engine.otherplayer);
|
||||
PublishCurrentState();
|
||||
}
|
||||
// here was have a pause on previous versions now its on send_draw_event
|
||||
Engine.switchUserIdx();
|
||||
}
|
||||
public bool iniciaJugadores(string rutaWarrior1, string rutaWarrior2, string nameWarrior1, string nameWarrior2)
|
||||
{
|
||||
ClearHistory();
|
||||
initmemoria();
|
||||
string res = Engine.Init(new string[] {
|
||||
rutaWarrior1,
|
||||
rutaWarrior2
|
||||
},
|
||||
new string[] {
|
||||
nameWarrior1,
|
||||
nameWarrior2
|
||||
}
|
||||
);
|
||||
Console.WriteLine("RES = " + res);
|
||||
if (res == "OK")
|
||||
{
|
||||
// seteamos el jugador 1
|
||||
Engine.switchUser(1);
|
||||
pinta(Engine.GetAddressProgram(), Engine.GetSizeProgram(), "r");
|
||||
// dibujamos la pantalla del jugador 1
|
||||
drawscreen(1);//, Engine.players[1].actual.ins, Engine.players[1].actual.dasm, Engine.players[1].actual.regs, Engine.players[1].actual.ipc());
|
||||
drawPC(1);
|
||||
// seteamos el jugador 0
|
||||
Engine.switchUser(0);
|
||||
pinta(Engine.GetAddressProgram(), Engine.GetSizeProgram(), "b");
|
||||
// dibujamos la pantalla del jugador 0
|
||||
drawscreen(0);//, Engine.players[0].actual.ins, Engine.players[0].actual.dasm, Engine.players[0].actual.regs, Engine.players[0].actual.ipc());
|
||||
drawPC(0);
|
||||
// ponemos el marco en el jugador0
|
||||
drawplayerturn(0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool bResetArena = false;
|
||||
public void stepCombate()
|
||||
{
|
||||
Debug.WriteLine("r2wars:stepCombate");
|
||||
status = "Paused — advanced 1 cycle";
|
||||
if (bInCombat)
|
||||
{
|
||||
|
||||
if (!bDead)
|
||||
{
|
||||
if (bResetArena)
|
||||
{
|
||||
bResetArena = false;
|
||||
Engine.ReiniciaGame(true);
|
||||
// Actualizamos la pantalla indicando que pinte los programas
|
||||
resetTablero();
|
||||
drawPC(Engine.thisplayer);
|
||||
drawPC(Engine.otherplayer);
|
||||
drawscreen(Engine.thisplayer);
|
||||
drawscreen(Engine.otherplayer);
|
||||
PublishCurrentState();
|
||||
return;
|
||||
}
|
||||
|
||||
totalciclos++;
|
||||
if (totalciclos > MAX_CYCLES)
|
||||
{
|
||||
nExausted++;
|
||||
if (nExausted > 2)
|
||||
{
|
||||
bInCombat = false;
|
||||
bThreadIni = false;
|
||||
bStopProcess = false;
|
||||
RoundExhausted();
|
||||
CombatEnd(true);
|
||||
nExausted = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RoundExhausted();
|
||||
totalciclos = 0;
|
||||
bResetArena = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ExecuteRoundInstruction(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
victorias[Engine.thisplayer]++;
|
||||
if (nRound == 3 || victorias[1] == 2 || victorias[0] == 2)
|
||||
{
|
||||
bInCombat = false;
|
||||
bThreadIni = false;
|
||||
bStopProcess = false;
|
||||
RoundEnd();
|
||||
CombatEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
RoundEnd();
|
||||
bDead = false;
|
||||
totalciclos = 0;
|
||||
bResetArena = true;
|
||||
nRound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void iniciaCombate()
|
||||
{
|
||||
status = "Running";
|
||||
bThreadIni = true;
|
||||
gameLoopTask = Task.Factory.StartNew(() =>
|
||||
{
|
||||
// Jugamos el combate mientras no hayan muertos
|
||||
Debug.WriteLine("gameLoopTask: Ini.");
|
||||
//int nexausted = 0;
|
||||
while (bInCombat)
|
||||
{
|
||||
|
||||
while (!bDead)
|
||||
{
|
||||
if (bStopProcess)
|
||||
{
|
||||
bThreadIni = false;
|
||||
bStopProcess = false;
|
||||
Debug.WriteLine("gameLoopTask: Fin (stopprocess).");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bResetArena)
|
||||
{
|
||||
bResetArena = false;
|
||||
Engine.ReiniciaGame(true);
|
||||
// Actualizamos la pantalla indicando que pinte los programas
|
||||
resetTablero();
|
||||
drawPC(Engine.thisplayer);
|
||||
drawPC(Engine.otherplayer);
|
||||
drawscreen(Engine.thisplayer);
|
||||
drawscreen(Engine.otherplayer);
|
||||
PublishCurrentState();
|
||||
if (bStopAtRoundEnd)
|
||||
{
|
||||
bThreadIni = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
totalciclos++;
|
||||
if (totalciclos > MAX_CYCLES)
|
||||
{
|
||||
nExausted++;
|
||||
if (nExausted > 2)
|
||||
{
|
||||
bInCombat = false;
|
||||
bThreadIni = false;
|
||||
bStopProcess = false;
|
||||
RoundExhausted();
|
||||
CombatEnd(true);
|
||||
nExausted = 0;
|
||||
Debug.WriteLine("gameLoopTask: Fin(draw)");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RoundExhausted();
|
||||
totalciclos = 0;
|
||||
bResetArena = true;
|
||||
if (bStopAtRoundEnd)
|
||||
{
|
||||
bThreadIni = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ExecuteRoundInstruction(false);
|
||||
}
|
||||
|
||||
victorias[Engine.thisplayer]++;
|
||||
if (nRound == 3 || victorias[1] == 2 || victorias[0] == 2)
|
||||
{
|
||||
bInCombat = false;
|
||||
bThreadIni = false;
|
||||
bStopProcess = false;
|
||||
RoundEnd();
|
||||
CombatEnd();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
RoundEnd();
|
||||
bDead = false;
|
||||
totalciclos = 0;
|
||||
bResetArena = true;
|
||||
nRound++;
|
||||
if (bStopAtRoundEnd)
|
||||
{
|
||||
bThreadIni = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteLine("gameLoopTask: Fin");
|
||||
});
|
||||
}
|
||||
public bool playcombat(string rutaWarrior1, string rutaWarrior2, string nameWarrior1, string nameWarrior2, bool bSingleRound, bool autoStart)
|
||||
{
|
||||
if (iniciaJugadores(rutaWarrior1, rutaWarrior2, nameWarrior1, nameWarrior2))
|
||||
{
|
||||
// ejecutamos el combate
|
||||
this.bInCombat = true; // indicamos que estamos en un combate
|
||||
this.bSingleRound = bSingleRound; // indicamos que No queremos un unico round
|
||||
this.bStopProcess = false;
|
||||
this.victorias[0] = 0;
|
||||
this.victorias[1] = 0;
|
||||
this.nRound = 0;
|
||||
this.nExausted = 0;
|
||||
this.bDead = false;
|
||||
this.totalciclos = 0;
|
||||
status = autoStart ? "Running" : "Paused — ready to step";
|
||||
PublishCurrentState();
|
||||
if (autoStart)
|
||||
{
|
||||
iniciaCombate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void StopCombate()
|
||||
{
|
||||
while (bThreadIni)
|
||||
{
|
||||
this.bStopProcess = true;
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
if (bInCombat)
|
||||
status = "Paused";
|
||||
}
|
||||
public void CancelCombat()
|
||||
{
|
||||
StopCombate();
|
||||
bInCombat = false;
|
||||
bStopProcess = false;
|
||||
bThreadIni = false;
|
||||
status = "Idle";
|
||||
}
|
||||
public string prevLog()
|
||||
{
|
||||
UiHistoryEntry entry;
|
||||
lock (historyLock)
|
||||
{
|
||||
if (historyIndex <= 0 || uiHistory.Count == 0)
|
||||
return "";
|
||||
historyIndex--;
|
||||
entry = uiHistory[historyIndex];
|
||||
}
|
||||
return json_output(entry);
|
||||
}
|
||||
public string nextLog()
|
||||
{
|
||||
UiHistoryEntry entry;
|
||||
lock (historyLock)
|
||||
{
|
||||
if (historyIndex < 0 || historyIndex >= uiHistory.Count - 1)
|
||||
return "";
|
||||
historyIndex++;
|
||||
entry = uiHistory[historyIndex];
|
||||
}
|
||||
return json_output(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RootNamespace>r2warsTorneo</RootNamespace>
|
||||
<AssemblyName>r2wars</AssemblyName>
|
||||
<AssemblyTitle>r2wars</AssemblyTitle>
|
||||
<Product>r2wars</Product>
|
||||
<Version>0.4.0</Version>
|
||||
<Nullable>disable</Nullable>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="wwwroot/**" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "r2wars", "r2wars.csproj", "{7C07AB0A-D2B5-4546-B5B2-6DC6E77E40D1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7C07AB0A-D2B5-4546-B5B2-6DC6E77E40D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7C07AB0A-D2B5-4546-B5B2-6DC6E77E40D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7C07AB0A-D2B5-4546-B5B2-6DC6E77E40D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7C07AB0A-D2B5-4546-B5B2-6DC6E77E40D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,251 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace r2warsTorneo
|
||||
{
|
||||
public static class r2warsWebSocket
|
||||
{
|
||||
private const int MaxMessageSize = 1024 * 1024;
|
||||
private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
public static async Task HandleAsync(WebSocket socket, CancellationToken cancellationToken)
|
||||
{
|
||||
Channel<string> outgoing = Channel.CreateUnbounded<string>(new UnboundedChannelOptions
|
||||
{
|
||||
SingleReader = true,
|
||||
SingleWriter = false
|
||||
});
|
||||
|
||||
MyHandler1 drawHandler = (sender, drawEvent) =>
|
||||
{
|
||||
r2warsStatic.r2w.sync_var = false;
|
||||
outgoing.Writer.TryWrite(drawEvent.message);
|
||||
};
|
||||
|
||||
using CancellationTokenSource connectionCancellation =
|
||||
CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
CancellationToken connectionToken = connectionCancellation.Token;
|
||||
|
||||
r2warsStatic.r2w.Event_draw += drawHandler;
|
||||
outgoing.Writer.TryWrite(r2warsStatic.torneo.GetStateJson());
|
||||
|
||||
try
|
||||
{
|
||||
Task receiveTask = ReceiveLoopAsync(socket, outgoing.Writer, connectionToken);
|
||||
Task sendTask = SendLoopAsync(socket, outgoing.Reader, connectionToken);
|
||||
|
||||
await Task.WhenAny(receiveTask, sendTask);
|
||||
connectionCancellation.Cancel();
|
||||
outgoing.Writer.TryComplete();
|
||||
|
||||
try
|
||||
{
|
||||
await Task.WhenAll(receiveTask, sendTask);
|
||||
}
|
||||
catch (OperationCanceledException) when (connectionToken.IsCancellationRequested)
|
||||
{
|
||||
}
|
||||
catch (WebSocketException)
|
||||
{
|
||||
// The peer disconnected without completing a close handshake.
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
r2warsStatic.r2w.Event_draw -= drawHandler;
|
||||
outgoing.Writer.TryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ReceiveLoopAsync(
|
||||
WebSocket socket,
|
||||
ChannelWriter<string> outgoing,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
byte[] buffer = new byte[4096];
|
||||
|
||||
while (socket.State == WebSocketState.Open)
|
||||
{
|
||||
using MemoryStream message = new MemoryStream();
|
||||
WebSocketReceiveResult result;
|
||||
|
||||
do
|
||||
{
|
||||
result = await socket.ReceiveAsync(
|
||||
new ArraySegment<byte>(buffer), cancellationToken);
|
||||
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
{
|
||||
await socket.CloseOutputAsync(
|
||||
WebSocketCloseStatus.NormalClosure,
|
||||
"Closing",
|
||||
CancellationToken.None);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.MessageType != WebSocketMessageType.Text)
|
||||
{
|
||||
await socket.CloseAsync(
|
||||
WebSocketCloseStatus.InvalidMessageType,
|
||||
"Only text commands are supported.",
|
||||
cancellationToken);
|
||||
return;
|
||||
}
|
||||
|
||||
message.Write(buffer, 0, result.Count);
|
||||
if (message.Length > MaxMessageSize)
|
||||
{
|
||||
await socket.CloseAsync(
|
||||
WebSocketCloseStatus.MessageTooBig,
|
||||
"Command is too large.",
|
||||
cancellationToken);
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (!result.EndOfMessage);
|
||||
|
||||
string response = Dispatch(Encoding.UTF8.GetString(message.ToArray()));
|
||||
if (!string.IsNullOrEmpty(response))
|
||||
outgoing.TryWrite(response);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task SendLoopAsync(
|
||||
WebSocket socket,
|
||||
ChannelReader<string> outgoing,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await foreach (string message in outgoing.ReadAllAsync(cancellationToken))
|
||||
{
|
||||
byte[] payload = Encoding.UTF8.GetBytes(message);
|
||||
await socket.SendAsync(
|
||||
new ArraySegment<byte>(payload),
|
||||
WebSocketMessageType.Text,
|
||||
true,
|
||||
cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static string Dispatch(string command)
|
||||
{
|
||||
if (command.TrimStart().StartsWith("{", StringComparison.Ordinal))
|
||||
{
|
||||
try
|
||||
{
|
||||
return DispatchJson(command);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
return JsonSerializer.Serialize(new
|
||||
{
|
||||
type = "error",
|
||||
message = exception.Message,
|
||||
recoverable = true
|
||||
}, JsonOptions);
|
||||
}
|
||||
}
|
||||
switch (command)
|
||||
{
|
||||
case "cmd_state":
|
||||
return r2warsStatic.torneo.GetStateJson();
|
||||
case "cmd_prevlog":
|
||||
return r2warsStatic.r2w.prevLog();
|
||||
case "cmd_nextlog":
|
||||
return r2warsStatic.r2w.nextLog();
|
||||
case "cmd_load":
|
||||
r2warsStatic.torneo.LoadTournamentPlayers();
|
||||
break;
|
||||
case "cmd_reset":
|
||||
r2warsStatic.torneo.ResetTournament();
|
||||
break;
|
||||
case "cmd_run":
|
||||
r2warsStatic.torneo.RunTournamentCombats();
|
||||
break;
|
||||
case "cmd_stop":
|
||||
r2warsStatic.torneo.StopActualCombat();
|
||||
break;
|
||||
case "cmd_step":
|
||||
case "cmd_next":
|
||||
r2warsStatic.torneo.StepTournamentCombats();
|
||||
break;
|
||||
case "cmd_dbg4":
|
||||
r2warsStatic.r2w.bStopAtRoundStart = false;
|
||||
break;
|
||||
case "cmd_dbg4si":
|
||||
r2warsStatic.r2w.bStopAtRoundStart = true;
|
||||
break;
|
||||
case "cmd_dbg5":
|
||||
r2warsStatic.r2w.bStopAtRoundEnd = false;
|
||||
break;
|
||||
case "cmd_dbg5si":
|
||||
r2warsStatic.r2w.bStopAtRoundEnd = true;
|
||||
break;
|
||||
case "moreflow":
|
||||
r2warsStatic.r2w.sync_var = true;
|
||||
return "none";
|
||||
case "arch_arm":
|
||||
r2warsStatic.r2w.answer = "arm";
|
||||
break;
|
||||
case "arch_x86":
|
||||
r2warsStatic.r2w.answer = "x86";
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string DispatchJson(string payload)
|
||||
{
|
||||
using JsonDocument document = JsonDocument.Parse(payload);
|
||||
JsonElement root = document.RootElement;
|
||||
string type = root.GetProperty("type").GetString() ?? "";
|
||||
switch (type)
|
||||
{
|
||||
case "bots":
|
||||
return JsonSerializer.Serialize(new
|
||||
{
|
||||
type = "bots",
|
||||
warriors = r2warsStatic.torneo.GetWarriorSources()
|
||||
}, JsonOptions);
|
||||
case "assemble":
|
||||
{
|
||||
int requestId = root.GetProperty("requestId").GetInt32();
|
||||
BrowserWarriorSource warrior = root.GetProperty("warrior")
|
||||
.Deserialize<BrowserWarriorSource>(JsonOptions);
|
||||
WarriorAssemblyResult result = WarriorCompiler.Assemble(warrior);
|
||||
return JsonSerializer.Serialize(new
|
||||
{
|
||||
type = "assembly",
|
||||
requestId,
|
||||
ok = result.Ok,
|
||||
bytes = Array.ConvertAll(result.Bytes, value => (int)value),
|
||||
size = result.Size,
|
||||
message = result.Message
|
||||
}, JsonOptions);
|
||||
}
|
||||
case "load":
|
||||
case "start":
|
||||
{
|
||||
BrowserWarriorSource[] warriors = root.GetProperty("warriors")
|
||||
.Deserialize<BrowserWarriorSource[]>(JsonOptions) ?? Array.Empty<BrowserWarriorSource>();
|
||||
r2warsStatic.torneo.LoadTournamentSources(warriors);
|
||||
if (type == "start")
|
||||
r2warsStatic.torneo.RunTournamentCombats();
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException("Unknown browser message type: " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 448 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 505 KiB |
@@ -0,0 +1,87 @@
|
||||
var e=()=>Array.from({length:1024},()=>``),t=()=>({workflow:`loading`,message:`Loading radare2 WebAssembly…`,player1:{name:`Player 1`,regs:``,code:``},player2:{name:`Player 2`,regs:``,code:``},memory:e(),console:`[r2wars wasm]`,status:`Loading`,scores:`No tournament loaded.`,completedCombats:0,totalCombats:0,activePlayer:-1,historyPosition:0,historyCount:0,canBrowseEarlier:!1,canBrowseLater:!1}),n=[[`.arm-16.`,{id:`arm-16`,arch:`arm`,bits:16}],[`.arm-32.`,{id:`arm-32`,arch:`arm`,bits:32}],[`.arm-64.`,{id:`arm-64`,arch:`arm`,bits:64}],[`.mips-32.`,{id:`mips-32`,arch:`mips`,bits:32}],[`.mips-64.`,{id:`mips-64`,arch:`mips`,bits:64}],[`.x86-32.`,{id:`x86-32`,arch:`x86`,bits:32}],[`.x86-64.`,{id:`x86-64`,arch:`x86`,bits:64}],[`.riscv-32.`,{id:`riscv-32`,arch:`riscv`,bits:32}],[`.riscv-64.`,{id:`riscv-64`,arch:`riscv`,bits:64}],[`.gb.`,{id:`gb`,arch:`gb`,bits:16}],[`.8051.`,{id:`8051`,arch:`8051`,bits:8,cpu:`8051-shared-code-xdata`}]];function r(e){let t=e.toLowerCase(),r=n.find(([e])=>t.includes(e));if(!r)throw Error(`${e}: architecture must be encoded in the filename, for example .x86-32.asm or .arm-32.asm`);return r[1]}function i(e){return e.map(e=>({...e}))}function a(e,t){let n=i(e);for(let e of t){let t=n.findIndex(t=>t.name.toLowerCase()===e.name.toLowerCase());t>=0?n[t]={...e}:n.push({...e})}return n}function o(e){let t=new Set(e.map(e=>e.name.toLowerCase())),n=1;for(;t.has(`new-warrior-${n}.x86-32.asm`);)n++;return{name:`new-warrior-${n}.x86-32.asm`,source:`start:
|
||||
nop
|
||||
jmp start
|
||||
`}}function s(e){if(e.length<2)throw Error(`Add at least two bots before starting a tournament.`);let t=new Set;for(let n of e){let e=n.name.trim();if(!e.toLowerCase().endsWith(`.asm`))throw Error(`${e||`Unnamed bot`}: filename must end in .asm`);r(e);let i=e.toLowerCase();if(t.has(i))throw Error(`Duplicate bot filename: ${e}`);if(t.add(i),!n.source.trim())throw Error(`${e}: source is empty`)}}var c=null,l=0,u=null,d=null,f=!1,p=t(),m=!1,h=!1,g=[],_=-1,v=!1,y=`replace`,b=0,x=e=>{let t=document.getElementById(e);if(!t)throw Error(`Missing UI element #${e}`);return t};function S(e){if(!c||c.readyState!==WebSocket.OPEN)throw Error(`The .NET connection is not ready`);c.send(e.type===`command`?e.command:JSON.stringify(e))}function C(e){m&&(h=!0,S({type:`command`,command:e}),G())}function w(){document.title=`r2wars — .NET arena`;let e=document.createElement(`meta`);e.name=`description`,e.content=`Run multi-architecture r2wars tournaments with the native .NET and radare2 engine.`,document.head.append(e);let t=document.createElement(`style`);t.textContent=`
|
||||
.connection.local { background:#d8e8ff; color:#174f85; }
|
||||
.drop-active::after { content:'Drop .asm warriors to load them'; position:fixed; inset:18px; z-index:10; display:grid; place-items:center; border:4px dashed springgreen; background:rgba(0,0,0,.88); color:springgreen; font:700 1.5rem monospace; }
|
||||
.wasm-note { color:#444; font-size:.72em; margin-right:auto; }
|
||||
#report_download { margin-left:8px; position:absolute; right:100px; top:24px; width:auto; padding:7px 18px; }
|
||||
.control-row { grid-template-columns:repeat(3,1fr); }
|
||||
.bot-manager[hidden] { display:none; }
|
||||
.bot-manager { position:fixed; inset:2%; z-index:20; display:grid; place-items:center; background:rgba(0,0,0,.84); border:3px solid #999; border-radius:7px; }
|
||||
.bot-manager-panel { box-sizing:border-box; display:flex; flex-direction:column; width:min(1100px,96%); height:min(760px,94%); overflow:hidden; color:#111; background:#ddd; border:2px solid #eee; box-shadow:0 12px 42px #000; }
|
||||
.bot-manager-header { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:10px 14px; color:white; background:linear-gradient(90deg,#123b8d,#8b1717); }
|
||||
.bot-manager-header h2 { margin:0; font-size:1.15rem; }
|
||||
.bot-manager-header span { font-size:.78rem; }
|
||||
.bot-manager-body { min-height:0; flex:1; display:grid; grid-template-columns:minmax(220px,30%) 1fr; gap:10px; padding:10px; }
|
||||
.bot-sidebar,.bot-editor { min-height:0; display:flex; flex-direction:column; gap:8px; }
|
||||
.bot-editor.no-selection > :not(.bot-editor-empty) { display:none; }
|
||||
.bot-list { min-height:120px; flex:1; overflow:auto; padding:4px; background:#171717; border:1px inset #aaa; }
|
||||
.bot-list button { margin-bottom:4px; padding:7px 8px; overflow:hidden; text-align:left; text-overflow:ellipsis; white-space:nowrap; color:#e8e8e8; background:#292929; border:1px solid #555; }
|
||||
.bot-list button.selected { color:#111; background:#9ed1ff; border-color:#3275aa; font-weight:bold; }
|
||||
.bot-sidebar-actions,.bot-manager-footer { display:flex; gap:8px; }
|
||||
.bot-sidebar-actions button,.bot-manager-footer button { width:auto; padding:7px 14px; }
|
||||
.bot-editor label { font-size:.8rem; font-weight:bold; }
|
||||
.bot-editor input,.bot-editor textarea { box-sizing:border-box; width:100%; color:#d8ffd8; background:#111; border:1px inset #aaa; font:14px/1.4 Consolas,'Courier New',monospace; }
|
||||
.bot-editor input { padding:7px; }
|
||||
.bot-editor textarea { min-height:180px; flex:1; padding:10px; resize:none; tab-size:2; }
|
||||
.bot-assembly { min-height:84px; max-height:150px; display:flex; flex-direction:column; gap:5px; overflow:auto; padding:7px; color:#ddd; background:#171717; border:1px inset #aaa; }
|
||||
.bot-assembly-summary { display:flex; align-items:center; gap:7px; font-size:.78rem; }
|
||||
.bot-assembly-summary strong { min-width:0; overflow-wrap:anywhere; }
|
||||
.bot-compile-indicator { width:11px; height:11px; flex:0 0 11px; border-radius:50%; background:#777; box-shadow:0 0 5px #555; }
|
||||
.bot-compile-indicator.pending { background:#e5b72f; box-shadow:0 0 6px #e5b72f; }
|
||||
.bot-compile-indicator.valid { background:#39e75f; box-shadow:0 0 6px #39e75f; }
|
||||
.bot-compile-indicator.invalid { background:#f04444; box-shadow:0 0 6px #f04444; }
|
||||
.bot-assembly-size { margin-left:auto; color:#9ed1ff; white-space:nowrap; }
|
||||
.bot-byte-array { min-height:38px; margin:0; overflow:auto; color:#b7e6ff; font:12px/1.35 Consolas,'Courier New',monospace; white-space:pre-wrap; word-break:break-all; }
|
||||
.bot-editor-empty { display:grid; flex:1; place-items:center; color:#555; border:1px dashed #999; }
|
||||
.bot-manager-footer { align-items:center; padding:9px 12px; border-top:1px solid #999; }
|
||||
.bot-manager-status { min-height:1.2em; flex:1; color:#444; font-size:.78rem; }
|
||||
.bot-manager-status.error { color:#8c1010; font-weight:bold; }
|
||||
#bot_start { background:#d8f5de; border-color:#318244; font-weight:bold; }
|
||||
@media (max-width: 900px), (orientation: portrait) {
|
||||
.bot-manager { inset:0; border:0; }
|
||||
.bot-manager-panel { height:100%; width:100%; }
|
||||
.bot-manager-body { grid-template-columns:1fr; grid-template-rows:minmax(150px,32%) 1fr; }
|
||||
.bot-manager-header span { display:none; }
|
||||
}
|
||||
`,document.head.append(t);let n=document.createElement(`input`);n.type=`file`,n.accept=`.asm,text/plain`,n.multiple=!0,n.hidden=!0,n.setAttribute(`aria-label`,`Choose warrior assembly files`),document.body.append(n);let r=document.querySelector(`.inspection-row`);if(r){let e=document.createElement(`span`);e.className=`wasm-note`,e.textContent=`Native engine · drop .asm files anywhere`,r.prepend(e)}let i=document.createElement(`button`);i.id=`cmd_bots`,i.textContent=`Bots`,i.title=`Add, remove, or edit bots for the next tournament`,document.querySelector(`.control-row`)?.append(i);let a=document.createElement(`div`);a.id=`bot_manager`,a.className=`bot-manager`,a.hidden=!0,a.setAttribute(`role`,`dialog`),a.setAttribute(`aria-modal`,`true`),a.setAttribute(`aria-labelledby`,`bot_manager_title`),a.innerHTML=`
|
||||
<div class="bot-manager-panel">
|
||||
<header class="bot-manager-header">
|
||||
<h2 id="bot_manager_title">Bot manager</h2>
|
||||
<span>Draft changes are loaded only when a new tournament starts</span>
|
||||
</header>
|
||||
<div class="bot-manager-body">
|
||||
<aside class="bot-sidebar">
|
||||
<strong id="bot_count">0 bots</strong>
|
||||
<div id="bot_list" class="bot-list" role="listbox" aria-label="Loaded bots"></div>
|
||||
<div class="bot-sidebar-actions">
|
||||
<button id="bot_add" type="button">New bot</button>
|
||||
<button id="bot_import" type="button">Import .asm</button>
|
||||
</div>
|
||||
</aside>
|
||||
<section class="bot-editor">
|
||||
<label for="bot_name">Filename and architecture</label>
|
||||
<input id="bot_name" type="text" autocomplete="off" spellcheck="false" placeholder="name.x86-32.asm">
|
||||
<label for="bot_source">Assembly source</label>
|
||||
<textarea id="bot_source" spellcheck="false" aria-label="Bot assembly source"></textarea>
|
||||
<div class="bot-assembly" aria-live="polite">
|
||||
<div class="bot-assembly-summary">
|
||||
<span id="bot_compile_indicator" class="bot-compile-indicator" aria-hidden="true"></span>
|
||||
<strong id="bot_compile_status">Not checked</strong>
|
||||
<span id="bot_assembly_size" class="bot-assembly-size">0 bytes</span>
|
||||
</div>
|
||||
<pre id="bot_byte_array" class="bot-byte-array">[]</pre>
|
||||
</div>
|
||||
<div class="bot-sidebar-actions">
|
||||
<button id="bot_delete" type="button">Delete selected bot</button>
|
||||
</div>
|
||||
<div id="bot_editor_empty" class="bot-editor-empty" hidden>Select a bot to edit its source.</div>
|
||||
</section>
|
||||
</div>
|
||||
<footer class="bot-manager-footer">
|
||||
<span id="bot_manager_status" class="bot-manager-status" role="status"></span>
|
||||
<button id="bot_close" type="button">Close</button>
|
||||
<button id="bot_start" type="button">Start new tournament</button>
|
||||
</footer>
|
||||
</div>`,document.body.append(a);let o=document.createElement(`button`);return o.id=`report_download`,o.textContent=`Download report`,o.hidden=!0,x(`overlay`).append(o),o.addEventListener(`click`,re),n}var T=w();T.addEventListener(`change`,async()=>{if(T.files?.length){let e=await D(Array.from(T.files));g=y===`replace`?e:a(g,e);let t=e.at(-1)?.name.toLowerCase();_=t?g.findIndex(e=>e.name.toLowerCase()===t):-1,v=!0,j()}T.value=``}),x(`cmd_load`).addEventListener(`click`,()=>{y=`replace`,T.click()}),x(`cmd_bots`).addEventListener(`click`,j),x(`cmd_run`).addEventListener(`click`,()=>{p.workflow===`running`?C(`cmd_stop`):p.workflow===`paused`?C(`cmd_run`):A()}),x(`cmd_step`).addEventListener(`click`,()=>C(`cmd_step`)),x(`cmd_reset`).addEventListener(`click`,()=>{(p.workflow!==`running`&&p.workflow!==`paused`||window.confirm(`Reset this tournament? Current progress and scores will be cleared.`))&&ne()}),x(`cmd_scores`).addEventListener(`click`,X),x(`log_prev`).addEventListener(`click`,()=>C(`cmd_prevlog`)),x(`log_next`).addEventListener(`click`,()=>C(`cmd_nextlog`)),x(`score_close`).addEventListener(`click`,Q),x(`nowarriorsclose`).addEventListener(`click`,$),x(`bot_add`).addEventListener(`click`,N),x(`bot_import`).addEventListener(`click`,()=>{y=`merge`,T.click()}),x(`bot_delete`).addEventListener(`click`,P),x(`bot_close`).addEventListener(`click`,M),x(`bot_start`).addEventListener(`click`,A),x(`bot_name`).addEventListener(`input`,e=>{_<0||(g[_].name=e.currentTarget.value,v=!0,I(),R(),G(),z())}),x(`bot_source`).addEventListener(`input`,e=>{_<0||(g[_].source=e.currentTarget.value,v=!0,R(),z())}),x(`overlay`).addEventListener(`click`,e=>{e.target===x(`overlay`)&&Q()}),x(`bot_manager`).addEventListener(`click`,e=>{e.target===x(`bot_manager`)&&M()}),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&(x(`bot_manager`).hidden?(Q(),$()):M())}),document.addEventListener(`dragover`,e=>{e.preventDefault(),p.workflow!==`running`&&document.body.classList.add(`drop-active`)}),document.addEventListener(`dragleave`,e=>{e.relatedTarget||document.body.classList.remove(`drop-active`)}),document.addEventListener(`drop`,async e=>{if(e.preventDefault(),document.body.classList.remove(`drop-active`),p.workflow===`running`)return;let t=Array.from(e.dataTransfer?.files??[]).filter(e=>e.name.toLowerCase().endsWith(`.asm`));if(t.length){let e=await D(t);g=a(g,e);let n=e.at(-1)?.name.toLowerCase();_=n?g.findIndex(e=>e.name.toLowerCase()===n):-1,v=!0,j()}});async function E(e){e.type===`ready`?(m=!0,x(`connection`).textContent=`.NET server`,x(`connection`).className=`connection local`,f?S({type:`command`,command:`cmd_state`}):(f=!0,await O())):e.type===`bots`?(u?.(e.warriors),u=null,d=null):e.type===`assembly`?B(e):e.type===`state`?(h=!1,p=ee(p,e.state),K()):e.recoverable?(h=!1,d?.(Error(e.message)),u=null,d=null,f&&(j(),R(e.message)),G()):V(e.message)}function ee(e,t){return{...e,...t,player1:{...e.player1,...t.player1},player2:{...e.player2,...t.player2},memory:t.memory??e.memory}}async function D(e){return Promise.all(e.map(async e=>({name:e.name,source:await e.text()})))}async function O(){try{g=i(await te()),_=g.length?0:-1,v=!1,S({type:`load`,warriors:i(g)})}catch(e){p.workflow=`idle`,p.message=`Choose at least two warrior files. Bundled examples could not be loaded: ${e instanceof Error?e.message:e}`,K()}}function te(){return new Promise((e,t)=>{u=e,d=t,c?.send(JSON.stringify({type:`bots`})),window.setTimeout(()=>{u===e&&(u=null,d=null,t(Error(`Timed out while loading bots from the .NET server`)))},5e3)})}function k(){return g.map(e=>({name:e.name.trim(),source:e.source}))}function A(){try{let e=k();s(e),g=i(e),v=!1,h=!0,M(),S({type:`start`,warriors:i(g)}),G()}catch(e){j(),R(e instanceof Error?e.message:String(e))}}function ne(){try{let e=k();s(e),g=i(e),v=!1,h=!0,S({type:`load`,warriors:i(g)}),G()}catch(e){j(),R(e instanceof Error?e.message:String(e))}}function j(){if(!m||p.workflow===`running`)return;let e=x(`bot_manager`);e.hidden=!1,L(),_>=0?x(`bot_name`).focus():x(`bot_add`).focus()}function M(){x(`bot_manager`).hidden=!0,x(`cmd_bots`).focus({preventScroll:!0})}function N(){g.push(o(g)),_=g.length-1,v=!0,L();let e=x(`bot_name`);e.focus(),e.select()}function P(){if(_<0)return;let e=g[_].name||`this bot`;window.confirm(`Delete ${e} from the next tournament?`)&&(g.splice(_,1),_=g.length?Math.min(_,g.length-1):-1,v=!0,L())}function F(e){_=e,L(),x(`bot_source`).focus()}function I(){let e=x(`bot_list`);e.replaceChildren(),g.forEach((t,n)=>{let r=document.createElement(`button`);r.type=`button`,r.textContent=t.name||`Unnamed bot`,r.title=t.name||`Unnamed bot`,r.classList.toggle(`selected`,n===_),r.setAttribute(`role`,`option`),r.setAttribute(`aria-selected`,String(n===_)),r.addEventListener(`click`,()=>F(n)),e.append(r)}),x(`bot_count`).textContent=`${g.length} bot${g.length===1?``:`s`}`,x(`cmd_bots`).textContent=`Bots (${g.length})`}function L(){_>=g.length&&(_=g.length-1),I();let e=_>=0?g[_]:void 0;document.querySelector(`Line truncated
|
||||
@@ -0,0 +1,722 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-r2wars-engine="dotnet">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="Run multi-architecture r2wars tournaments with radare2.">
|
||||
<title>r2wars</title>
|
||||
<style>
|
||||
button {
|
||||
min-width: 10px;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.connection {
|
||||
border-radius: 10px;
|
||||
color: #333;
|
||||
font-size: 0.78em;
|
||||
padding: 2px 7px;
|
||||
}
|
||||
|
||||
.connection.connected {
|
||||
background: #c7f4d0;
|
||||
color: #145b23;
|
||||
}
|
||||
|
||||
.connection.connecting {
|
||||
background: #fff2b7;
|
||||
}
|
||||
|
||||
.connection.disconnected {
|
||||
background: #ffd0d0;
|
||||
color: #7b1111;
|
||||
}
|
||||
|
||||
table {
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.addr {
|
||||
color: white;
|
||||
text-align: center;
|
||||
background-color: black;
|
||||
font-weight: bold;
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
.div1 {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.divM3 {
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
background-color: #e0e0e0;
|
||||
left: 30%;
|
||||
right: 30%;
|
||||
width: 40%;
|
||||
height: 16em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.divM2 {
|
||||
position: fixed;
|
||||
bottom: 16em;
|
||||
background-color: #e0e0e0;
|
||||
left: 30%;
|
||||
right: 30%;
|
||||
width: 40%;
|
||||
height: 132px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #a0a0a0;
|
||||
padding: 7px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.status-strip, .inspection-row {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.status-strip {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.workflow-badge {
|
||||
background: #d2d2d2;
|
||||
border-radius: 10px;
|
||||
font-size: 0.78em;
|
||||
font-weight: bold;
|
||||
padding: 2px 8px;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workflow-badge.ready { background: #d5e9ff; color: #174f85; }
|
||||
.workflow-badge.running { background: #c7f4d0; color: #145b23; }
|
||||
.workflow-badge.paused { background: #fff2b7; color: #705600; }
|
||||
.workflow-badge.finished { background: #d9ccff; color: #41257c; }
|
||||
|
||||
.progress {
|
||||
flex: 1;
|
||||
font-size: 0.78em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.workflow-message {
|
||||
height: 30px;
|
||||
line-height: 15px;
|
||||
margin: 5px 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.stage-notice {
|
||||
background: rgba(18, 18, 18, 0.92);
|
||||
border: 2px solid #aaa;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.55);
|
||||
color: white;
|
||||
left: 8%;
|
||||
padding: 18px 22px;
|
||||
position: absolute;
|
||||
right: 8%;
|
||||
text-align: center;
|
||||
top: 18%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.stage-notice[hidden] { display: none; }
|
||||
|
||||
.stage-notice strong {
|
||||
color: springgreen;
|
||||
display: block;
|
||||
font-size: 1.55em;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stage-notice.ready strong { color: #8fc7ff; }
|
||||
.stage-notice.finished strong { color: #c9b4ff; }
|
||||
|
||||
.control-row {
|
||||
display: grid;
|
||||
gap: 5px;
|
||||
grid-template-columns: 1.3fr 1.4fr 0.8fr 0.8fr 0.8fr;
|
||||
}
|
||||
|
||||
.control-row button, .inspection-row button {
|
||||
background: #f3f3f3;
|
||||
border: 1px solid #777;
|
||||
border-radius: 3px;
|
||||
min-height: 25px;
|
||||
}
|
||||
|
||||
.control-row button.primary {
|
||||
background: #d8f5de;
|
||||
border-color: #318244;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.control-row button.primary.pause {
|
||||
background: #fff0bd;
|
||||
border-color: #9a761c;
|
||||
}
|
||||
|
||||
.inspection-row {
|
||||
font-size: 0.75em;
|
||||
justify-content: flex-end;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.inspection-row button {
|
||||
max-width: 92px;
|
||||
}
|
||||
|
||||
.divM {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 30%;
|
||||
right: 30%;
|
||||
height: 100%;
|
||||
width: 40%;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.div2 {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.memory {
|
||||
overflow-y: hidden;
|
||||
height: 100%;
|
||||
background-color: #303030;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
text-align: center;
|
||||
color: white;
|
||||
background-color: #a0a0a0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.console {
|
||||
height: 14.5em;
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-family: Courier New;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
white-space: pre;
|
||||
overflow-y: scroll;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.console1 {
|
||||
height: 238px;
|
||||
background-color: black;
|
||||
width: 100%;
|
||||
color: white;
|
||||
font-family: Courier New;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
white-space: pre;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.console2 {
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
color: springgreen;
|
||||
font-family: Courier New;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
width: 100%;
|
||||
white-space: pre;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.s {
|
||||
background-color: green;
|
||||
color: black;
|
||||
font-family: Courier New;
|
||||
font-weight: bold;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
background-color: #909090;
|
||||
}
|
||||
|
||||
td {
|
||||
font-family: Courier New;
|
||||
border: 1px solid #a0a0a0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
button {
|
||||
min-width: 1px;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
div {
|
||||
font-family: Courier New;
|
||||
}
|
||||
|
||||
tr {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.player1 {
|
||||
background-color: blue;
|
||||
width: 100%;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 2em;
|
||||
font-family: Consolas, Courier New;
|
||||
overflow-x: hidden;
|
||||
text-align: left;
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
.player2 {
|
||||
color: white;
|
||||
width: 100%;
|
||||
background-color: red;
|
||||
font-weight: bold;
|
||||
font-size: 2em;
|
||||
font-family: Consolas, Courier New;
|
||||
overflow-x: hidden;
|
||||
text-align: left;
|
||||
padding-left: 0em;
|
||||
}
|
||||
|
||||
.active-dot {
|
||||
display: inline-block;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
margin: 0 0.5em;
|
||||
border: 2px solid white;
|
||||
border-radius: 50%;
|
||||
background-color: #4b4b4b;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.active-dot.active {
|
||||
background-color: #39e75f;
|
||||
box-shadow: 0 0 0.5em #39e75f;
|
||||
animation: active-pulse 0.8s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes active-pulse {
|
||||
from { transform: scale(0.85); }
|
||||
to { transform: scale(1.15); }
|
||||
}
|
||||
|
||||
.memtable {
|
||||
font-size: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
display: none;
|
||||
top: 1%;
|
||||
width: 90%;
|
||||
right: 5%;
|
||||
bottom: 1%;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
border-radius: 6px;
|
||||
border: 3px solid #a0a0a0;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-weight: bold;
|
||||
margin: 24px 80px 12px 30px;
|
||||
font-size: 40px;
|
||||
color: springgreen;
|
||||
}
|
||||
|
||||
.text1 {
|
||||
font-weight: bold;
|
||||
font-size: 1.4em;
|
||||
color: white;
|
||||
white-space: pre;
|
||||
margin: 20px 30px;
|
||||
max-height: calc(100% - 130px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.overlay-close {
|
||||
background: #e5e5e5;
|
||||
border: 1px solid #888;
|
||||
border-radius: 3px;
|
||||
padding: 7px 18px;
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
top: 24px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.win98 {
|
||||
display: none;
|
||||
top: 30%;
|
||||
left: 30%;
|
||||
right: 30%;
|
||||
z-index: 3;
|
||||
-webkit-font-smoothing: none;
|
||||
-moz-osx-font-smoothing: none;
|
||||
font-size: 11px;
|
||||
font-family: Tahoma, Verdana;
|
||||
color: #070707;
|
||||
position: absolute;
|
||||
margin: 0 auto;
|
||||
background: #bfbfbf;
|
||||
border: 1px solid;
|
||||
border-top-color: #dfdfdf;
|
||||
border-left-color: #dfdfdf;
|
||||
border-right-color: #808080;
|
||||
border-bottom-color: #808080;
|
||||
box-shadow: 1px 1px 0 0 #000;
|
||||
width: 400px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.win98 .content {
|
||||
padding: 7px 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.win98 .header {
|
||||
margin: 2px 2px 0;
|
||||
padding: 1px 2px;
|
||||
color: #fff;
|
||||
background: -webkit-linear-gradient(left, blue, red);
|
||||
background: linear-gradient(to right, blue, red);
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.legend1 {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
z-index: 2;
|
||||
background-color: black;
|
||||
left: 10px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.legend2 {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
z-index: 2;
|
||||
background-color: black;
|
||||
right: 10px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.legend {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
width: 10px;
|
||||
max-width: 10px;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.win98 button {
|
||||
-webkit-font-smoothing: none;
|
||||
-moz-osx-font-smoothing: none;
|
||||
font-size: 11px;
|
||||
font-family: Tahoma, Verdana;
|
||||
color: #070707;
|
||||
background: #bfbfbf;
|
||||
border: 1px solid;
|
||||
border-top-color: #dfdfdf;
|
||||
border-left-color: #dfdfdf;
|
||||
border-right-color: #808080;
|
||||
border-bottom-color: #808080;
|
||||
box-shadow: 1px 1px 0 0 #000;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
padding: 4px;
|
||||
cursor: default;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.win98 button:enabled {
|
||||
color: #070707;
|
||||
}
|
||||
|
||||
.win98 button:disabled {
|
||||
color: #818181;
|
||||
text-shadow: 1px 1px #fff;
|
||||
}
|
||||
|
||||
.win98 button:active:enabled {
|
||||
box-shadow: 1px 1px 0 0 #000 inset;
|
||||
border-top-color: #808080;
|
||||
border-left-color: #808080;
|
||||
border-right-color: #dfdfdf;
|
||||
border-bottom-color: #dfdfdf;
|
||||
}
|
||||
|
||||
/* On narrow or portrait screens, keep the arena visible before the code. */
|
||||
@media (max-width: 900px), (orientation: portrait) {
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.div1, .div2, .divM, .divM2, .divM3 {
|
||||
box-sizing: border-box;
|
||||
left: auto;
|
||||
position: relative;
|
||||
right: auto;
|
||||
top: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.div1, .div2 {
|
||||
height: 180px;
|
||||
min-height: 0;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.div1 table, .div2 table {
|
||||
height: 100% !important;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.player1, .player2 {
|
||||
box-sizing: border-box;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.5;
|
||||
overflow: hidden;
|
||||
padding-left: 0.5em;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.active-dot {
|
||||
height: 0.6em;
|
||||
margin: 0 0.35em;
|
||||
width: 0.6em;
|
||||
}
|
||||
|
||||
.console1 {
|
||||
box-sizing: border-box;
|
||||
font-size: 12px;
|
||||
height: 44px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.console2 {
|
||||
box-sizing: border-box;
|
||||
font-size: 11px;
|
||||
height: 94px;
|
||||
line-height: 1.2;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.divM {
|
||||
height: min(440px, 115vw);
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.divM table {
|
||||
height: 100% !important;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.memory {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.memtable {
|
||||
font-size: 9px;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.addr {
|
||||
width: 4em;
|
||||
}
|
||||
|
||||
.box {
|
||||
height: 0.9em;
|
||||
padding: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.divM2 {
|
||||
bottom: auto;
|
||||
min-height: 165px;
|
||||
}
|
||||
|
||||
.divM3 {
|
||||
bottom: auto;
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
.control-row {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.legend1, .legend2 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="overlay" class="overlay" role="dialog" aria-modal="true" aria-labelledby="score_title">
|
||||
<div id="score_title" class="text">Tournament scores</div>
|
||||
<button id="score_close" class="overlay-close">Close</button>
|
||||
<pre id="scores" class="text1"></pre>
|
||||
</div>
|
||||
<div id="nowarriorsdlg" class="win98" role="dialog" aria-modal="true" aria-labelledby="warriors-title">
|
||||
<div class="header">
|
||||
<span id="warriors-title">Warriors not found</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<center>
|
||||
<h3>Add at least two .asm warrior files to the warriors directory, then load again.</h3>
|
||||
<button id="nowarriorsclose">Close</button>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
<div class="legend1">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="legend" style="background-color:aqua">R</td>
|
||||
<td class="legend" style="background-color:violet">W</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="div1" style="overflow-y:hidden;">
|
||||
<table style="height:100%;width:100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="player1"><span id="active1" class="active-dot" aria-label="Player 1 is waiting"></span><span id="player1">Player1</span></td>
|
||||
</tr>
|
||||
<tr style="height:100%">
|
||||
<td valign="top" style="overflow-x:hidden;overflow-y:hidden">
|
||||
<div class="console1" id="regs1"></div>
|
||||
<div style="border: 1px solid #a0a0a0"></div>
|
||||
<div class="console2" id="code1"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="divM" style="overflow-x:hidden">
|
||||
<div id="stage_notice" class="stage-notice idle">
|
||||
<strong id="stage_title">No tournament loaded</strong>
|
||||
<span id="stage_detail">Load warriors to begin.</span>
|
||||
</div>
|
||||
<center class="">
|
||||
<table style="height:100%;overflow-x:scroll;width:100%">
|
||||
<tbody>
|
||||
<tr style="height:100%">
|
||||
<td valign="top"><div class="memory" id="memory"></div></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</center>
|
||||
</div>
|
||||
<div class="divM2">
|
||||
<div class="status-strip">
|
||||
<span id="workflow_badge" class="workflow-badge idle">idle</span>
|
||||
<span id="progress" class="progress">0 / 0 battles</span>
|
||||
<span id="connection" class="connection connecting" role="status">Connecting…</span>
|
||||
</div>
|
||||
<div id="workflow_message" class="workflow-message">Load warriors to begin.</div>
|
||||
<div class="control-row">
|
||||
<button id="cmd_load" title="Scan the warriors directory for .asm files">Load warriors</button>
|
||||
<button id="cmd_run" class="primary" title="Start or pause continuous tournament play">Start tournament</button>
|
||||
<button id="cmd_step" title="Advance exactly one engine cycle while paused">Step</button>
|
||||
<button id="cmd_scores" title="Show current standings">Scores</button>
|
||||
<button id="cmd_reset" title="Clear progress and scores for the loaded warriors">Reset</button>
|
||||
</div>
|
||||
<div class="inspection-row">
|
||||
<span>Execution history (paused):</span>
|
||||
<button id="log_prev" title="Show the earlier recorded state for both warriors">Earlier state</button>
|
||||
<button id="log_next" title="Show the later recorded state for both warriors">Later state</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divM3">
|
||||
<center class="">
|
||||
<table style="width:100%">
|
||||
<tbody>
|
||||
<tr style="height:100%">
|
||||
<td style="height:100%">
|
||||
<div id="console" class="console"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="height:100%">
|
||||
<td id="status">Idle</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</center>
|
||||
</div>
|
||||
<div class="legend2">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="legend" style="background-color:yellow">R</td>
|
||||
<td class="legend" style="background-color:orange">W</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="div2" style="overflow-y:hidden">
|
||||
<table style="height:100%;width:100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="player2"><span id="active2" class="active-dot" aria-label="Player 2 is waiting"></span><span id="player2">Player2</span></td>
|
||||
</tr>
|
||||
<tr style="height:100%">
|
||||
<td valign="top" style="overflow-x:hidden;overflow-y:hidden" height="100%" colspan="3">
|
||||
<div class="console1" id="regs2"></div>
|
||||
<div style="border: 1px solid #a0a0a0"></div>
|
||||
<div class="console2" id="code2"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script type="module" src="/assets/r2wars-ui.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
mov dptr, #kill
|
||||
loop:
|
||||
inc dptr
|
||||
inc dptr
|
||||
inc dptr
|
||||
inc a
|
||||
movx @dptr, a
|
||||
sjmp loop
|
||||
kill:
|
||||
@@ -0,0 +1,18 @@
|
||||
pack:
|
||||
; mov edi, 0xcccccccc
|
||||
; mov esi, 0xcccccccc
|
||||
; mov ebp, 0xcccccccc
|
||||
mov ebx, 0x00000400
|
||||
mov edx, 0x6060dc89
|
||||
mov ecx, 0x60606060
|
||||
mov eax, 0xf9eb6060
|
||||
unpack:
|
||||
mov esp, 0x20
|
||||
pushad
|
||||
add esp, 0x14 ; if shorter
|
||||
jmp esp
|
||||
loop:
|
||||
inc eax
|
||||
jmp loop
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
call init
|
||||
init:
|
||||
pop esp
|
||||
add esp, 0x26
|
||||
mov dword [eax], esp ; esp saved @0x0
|
||||
sub esp, 0x20
|
||||
save:
|
||||
popad
|
||||
jmp restore
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
restore:
|
||||
mov esp, dword [0x0]
|
||||
add esp, 0x20
|
||||
xor esi, esi
|
||||
mov dword [esi], esp
|
||||
pushad
|
||||
@@ -0,0 +1,22 @@
|
||||
# Anisse Astier
|
||||
.arch arm
|
||||
.bits 32
|
||||
.hex 0c008fe2
|
||||
.hex fe7fb0e8
|
||||
.hex 020ca0e3
|
||||
.hex fe7f80e8
|
||||
.hex 81ffa0e3
|
||||
.hex 3f0e00e2
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex 0600a0e8
|
||||
.hex f3ffffea
|
||||
.hex cccccccc
|
||||
.hex cccccccc
|
||||
@@ -0,0 +1,12 @@
|
||||
; when i say jump -- you say how high
|
||||
|
||||
mov eax, 0xfeebfeeb; feebfeeb
|
||||
mov ebx, eax
|
||||
mov ecx, eax
|
||||
mov edx, eax
|
||||
mov ebp, eax
|
||||
mov edi, eax
|
||||
mov esp, 0x3fc
|
||||
mov esi, 0x3fd
|
||||
mov [esi], 0xe6ff60
|
||||
jmp esi
|
||||
@@ -0,0 +1,18 @@
|
||||
sub x20, x20, 16;
|
||||
movk x21, 0x1ff;
|
||||
|
||||
bl start;
|
||||
start:
|
||||
movk x22, 0x8a;
|
||||
strb w22, [x30, 23]; // patch ORR -> AND
|
||||
ldp x0, x1, [x30, 16]; // copy
|
||||
ldp x2, x3, [x30, 32]; // copy
|
||||
|
||||
add x20, x20, 32;
|
||||
orr x20, x20, x21; // becomes AND
|
||||
stp x0, x1, [x20, 120]; // stomp
|
||||
stp x0, x1, [x20, 480]; // stomp
|
||||
stp x2, x3, [x20, 496]; // stomp
|
||||
stp x0, x1, [x20, 0]; // paste
|
||||
stp x2, x3, [x20, 16]; // paste
|
||||
br x20;
|
||||
@@ -0,0 +1,20 @@
|
||||
mov ebx, 0x69696969
|
||||
mov ecx, ebx
|
||||
mov edx, 0x400
|
||||
|
||||
mov edi, 0xd439c401
|
||||
mov esi, 0x60e04f0f
|
||||
mov ebp, 0xe4ff6060
|
||||
|
||||
mov esp, 0x215
|
||||
pushad
|
||||
mov esp, 0x25
|
||||
pushad
|
||||
mov esp, 0x3f9
|
||||
pushad
|
||||
|
||||
mov esp, 0x310
|
||||
pushad
|
||||
pushad
|
||||
mov eax, 0xB9
|
||||
jmp esp
|
||||
@@ -0,0 +1,11 @@
|
||||
; kaploombaa
|
||||
.arch x86
|
||||
.bits 32
|
||||
mov esp, 0x70;
|
||||
mov eax, 0x00008000;
|
||||
mov ebx, 0x0003ffff;
|
||||
mov edi, 0x000070bc;
|
||||
mov esi, 0x21c70100;
|
||||
mov ebp, 0xe4ff60df;
|
||||
pushal;
|
||||
jmp esp;
|
||||
@@ -0,0 +1,24 @@
|
||||
.bits 32
|
||||
.arch arm
|
||||
.hex 3f6e
|
||||
.hex a0e3
|
||||
.hex 0620
|
||||
.hex 00e3
|
||||
.hex 5121
|
||||
.hex 4ee3
|
||||
.hex 0030
|
||||
.hex 01e3
|
||||
.hex a031
|
||||
.hex 48e3
|
||||
.hex 3c40
|
||||
.hex 00e3
|
||||
.hex a148
|
||||
.hex 4ee3
|
||||
.hex 0f50
|
||||
.hex 0fe3
|
||||
.hex 4152
|
||||
.hex 4ee3
|
||||
.hex 0010
|
||||
.hex 8fe2
|
||||
.hex 3c00
|
||||
.hex a1e8
|
||||
@@ -0,0 +1,490 @@
|
||||
; Warrior X86 32 bits by goyo.
|
||||
; Despues del RevientaViejas (r2con2018), viene: 'GORDASCO'
|
||||
; bot para r2wars (r2con2020)
|
||||
; Básicamente un replicator con problemas de peso
|
||||
|
||||
.bits 32
|
||||
Main:
|
||||
CALL Boot
|
||||
Boot:
|
||||
POP ESI
|
||||
JMP replicator
|
||||
# Esto para engordar el binario a 512 bytes y reducir el area de busqueda inicial del otro bot a 512.
|
||||
# Si es rápido podría encontrar al otro antes de que se mueva si es que se mueve.
|
||||
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
|
||||
replicator:
|
||||
CLD
|
||||
MOV BX,0x3d7 ; memory top
|
||||
MOV EDI,ESI
|
||||
ADD SI,461 ; offset Payload - offset Main
|
||||
MOV EAX,ESI
|
||||
ADD EDI,40 ; only for 1st replication
|
||||
MOV [EDX],EAX ; Por si alguien se esconde en 0x0 o en 0x3ff y le pillo..
|
||||
MOV [EBX+36],EAX
|
||||
Payload:
|
||||
MOV ESI,EAX ; payload start
|
||||
MOV CL,0x0A ; loop rep // attack // copy to the last .byte 0xcc
|
||||
SUB EDI,40+40+3 ; separation ( 40 from last movsd + 40 from new movsd + 3 extra)
|
||||
JNC Nocheck ; check limits
|
||||
MOV EDI,EBX
|
||||
Nocheck:
|
||||
MOV EAX,EDI
|
||||
REP MOVSD ; replicator
|
||||
JMP EAX
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
; r2wars warrior by zutle
|
||||
; >> So you want to play the pusha game? :D
|
||||
;
|
||||
; The logic below generates the following code:
|
||||
;
|
||||
;
|
||||
;payload:
|
||||
; test sp, sp
|
||||
; jnz replicate
|
||||
; mov sp, 0x400
|
||||
;replicate:
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; mov [esp + 0xc], ecx
|
||||
; mov eax, esp
|
||||
; jmp eax
|
||||
|
||||
call start
|
||||
start:
|
||||
pop esp
|
||||
and esp, 0xffffff00
|
||||
add esp, 0x20
|
||||
mov edx, 0xe0ffe089
|
||||
mov ebx, 0x0c244c89
|
||||
mov ecx, 0x60606060
|
||||
mov ebp, 0x60606060
|
||||
mov esi, 0x0400bc66
|
||||
mov edi, 0x0475e485
|
||||
pushal
|
||||
mov [esp + 0xc], ecx
|
||||
mov eax, esp
|
||||
jmp eax
|
||||
@@ -0,0 +1,29 @@
|
||||
call get_eip
|
||||
|
||||
get_eip:
|
||||
|
||||
pop esp
|
||||
|
||||
|
||||
qq:
|
||||
|
||||
mov [esp+0x30], esp
|
||||
|
||||
pushad
|
||||
|
||||
pushad
|
||||
|
||||
pushad
|
||||
|
||||
popad
|
||||
|
||||
popad
|
||||
|
||||
popad
|
||||
add esp, ecx
|
||||
|
||||
dec ecx
|
||||
cmp esp, 0x80
|
||||
ja qq
|
||||
mov esp, 0x3a0
|
||||
jmp qq
|
||||
@@ -0,0 +1,33 @@
|
||||
; her isimizde hayirlisi olsun
|
||||
; pushad loopunu 0x14 civarına unpack ettikten sonra
|
||||
; oraya ziplayip 0x400'den geriye pushad yapmaya baslar
|
||||
; v3: a longer pushad init
|
||||
pack:
|
||||
; mov edi, 0xcccccccc
|
||||
; mov esi, 0xcccccccc
|
||||
; mov ebp, 0xcccccccc
|
||||
mov ebx, 0x00000400
|
||||
mov edx, 0x6060dc89
|
||||
mov ecx, 0x60606060
|
||||
mov eax, 0xf6eb6060
|
||||
unpack:
|
||||
mov esp, 0x220
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
add esp, 0x14 ; if shorter, tune this
|
||||
jmp esp
|
||||
@@ -0,0 +1,19 @@
|
||||
call init
|
||||
init:
|
||||
pop esp
|
||||
add esp, 0x26
|
||||
mov dword [eax], esp ; esp saved @0x0
|
||||
sub esp, 0x20
|
||||
save:
|
||||
popad
|
||||
jmp restore
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
restore:
|
||||
mov esp, dword [0x0]
|
||||
add esp, 0x20
|
||||
xor esi, esi
|
||||
mov dword [esi], esp
|
||||
pushad
|
||||
@@ -0,0 +1,15 @@
|
||||
mov eax, 0xc3c3c3c3
|
||||
mov ebx, 1024
|
||||
mov edx, 0xa0
|
||||
mov ebp, 0xe4ff6060
|
||||
mov esi, 0x606060e3
|
||||
mov edi, 0x420fd439
|
||||
call pwn
|
||||
pwn:
|
||||
pop esp
|
||||
sub esp,4
|
||||
pushad
|
||||
mov esp, 0x340
|
||||
pushad
|
||||
jmp esp
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Anisse Astier
|
||||
.arch arm
|
||||
.bits 32
|
||||
.hex 0c008fe2
|
||||
.hex fe7fb0e8
|
||||
.hex 020ca0e3
|
||||
.hex fe7f80e8
|
||||
.hex 81ffa0e3
|
||||
.hex 3f0e00e2
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex fe7fa0e8
|
||||
.hex 0600a0e8
|
||||
.hex f3ffffea
|
||||
.hex cccccccc
|
||||
.hex cccccccc
|
||||
@@ -0,0 +1,23 @@
|
||||
; when i say jump -- you say how high
|
||||
|
||||
mov eax, 0xffffffff
|
||||
mov ecx, eax
|
||||
mov edx, eax
|
||||
mov ebx, eax
|
||||
mov ebp, eax
|
||||
mov esi, eax
|
||||
|
||||
check:
|
||||
mov edi, 0x000
|
||||
cmp [edi], 0
|
||||
jne planb
|
||||
mov esp, 0x400
|
||||
inc edi
|
||||
mov [edi], 0xe7ff6060
|
||||
jmp edi
|
||||
|
||||
planb:
|
||||
mov edi, 0x3fb
|
||||
mov [edi], 0xe7ff6060
|
||||
mov esp, 0x3fa
|
||||
jmp edi
|
||||
@@ -0,0 +1,18 @@
|
||||
sub x20, x20, 16;
|
||||
movk x21, 0x1ff;
|
||||
|
||||
bl start;
|
||||
start:
|
||||
movk x22, 0x8a;
|
||||
strb w22, [x30, 23]; // patch ORR -> AND
|
||||
ldp x0, x1, [x30, 16]; // copy
|
||||
ldp x2, x3, [x30, 32]; // copy
|
||||
|
||||
add x20, x20, 32;
|
||||
orr x20, x20, x21; // becomes AND
|
||||
stp x0, x1, [x20, 120]; // stomp
|
||||
stp x0, x1, [x20, 480]; // stomp
|
||||
stp x2, x3, [x20, 496]; // stomp
|
||||
stp x0, x1, [x20, 0]; // paste
|
||||
stp x2, x3, [x20, 16]; // paste
|
||||
br x20;
|
||||
@@ -0,0 +1,20 @@
|
||||
mov ebx, 0x69696969
|
||||
mov ecx, ebx
|
||||
mov edx, 0x400
|
||||
|
||||
mov edi, 0xd439c401
|
||||
mov esi, 0x60e04f0f
|
||||
mov ebp, 0xe4ff6060
|
||||
|
||||
mov esp, 0x215
|
||||
pushad
|
||||
mov esp, 0x25
|
||||
pushad
|
||||
mov esp, 0x3f9
|
||||
pushad
|
||||
|
||||
mov esp, 0x310
|
||||
pushad
|
||||
pushad
|
||||
mov eax, 0xB9
|
||||
jmp esp
|
||||
@@ -0,0 +1,11 @@
|
||||
; kaploombaa
|
||||
.arch x86
|
||||
.bits 32
|
||||
mov esp, 0x70;
|
||||
mov eax, 0x00008000;
|
||||
mov ebx, 0x0003ffff;
|
||||
mov edi, 0x000070bc;
|
||||
mov esi, 0x21c70100;
|
||||
mov ebp, 0xe4ff60df;
|
||||
pushal;
|
||||
jmp esp;
|
||||
@@ -0,0 +1,21 @@
|
||||
;.arch arm
|
||||
.bits 32
|
||||
|
||||
.hex 00D04FE2 ; SUB SP,R15,0x00
|
||||
.hex FF5FBDE8 ; POP {R0-R12,R14}
|
||||
.hex 050D5DE3 ; r13 CMP SP,0x140
|
||||
.hex FFFF2DA9 ; r14 PUSHGE {R0-15}
|
||||
.hex FFFF2DA9 ; r12 PUSHGE
|
||||
.hex FFFF2DA9 ; r12 PUSHGE
|
||||
.hex FFFF2DA9 ; r11 PUSHGE
|
||||
.hex FFFF2DA9 ; r10 PUSHGE
|
||||
.hex 01DBA0D3 ; r9 orrle sp,r14,sp
|
||||
.hex 0DF0A0C1 ; r8 MOVGT R15,SP #jump if SP>=0
|
||||
.hex 24F05FE2 ; r6 SUBS R15,R15,0x24
|
||||
.hex 11111111 ; r5
|
||||
.hex 22222222 ; r4
|
||||
.hex cccccccc ; r3
|
||||
.hex 44444444 ; r2
|
||||
.hex 00040000 ; r1
|
||||
|
||||
|
||||
@@ -0,0 +1,490 @@
|
||||
; Warrior X86 32 bits by goyo.
|
||||
; Despues del RevientaViejas (r2con2018), viene: 'GORDASCO'
|
||||
; bot para r2wars (r2con2020)
|
||||
; Básicamente un replicator con problemas de peso
|
||||
|
||||
.bits 32
|
||||
Main:
|
||||
CALL Boot
|
||||
Boot:
|
||||
POP ESI
|
||||
JMP replicator
|
||||
# Esto para engordar el binario a 512 bytes y reducir el area de busqueda inicial del otro bot a 512.
|
||||
# Si es rápido podría encontrar al otro antes de que se mueva si es que se mueve.
|
||||
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
|
||||
replicator:
|
||||
CLD
|
||||
MOV BX,0x3d7 ; memory top
|
||||
MOV EDI,ESI
|
||||
ADD SI,461 ; offset Payload - offset Main
|
||||
MOV EAX,ESI
|
||||
ADD EDI,40 ; only for 1st replication
|
||||
MOV [EDX],EAX ; Por si alguien se esconde en 0x0 o en 0x3ff y le pillo..
|
||||
MOV [EBX+36],EAX
|
||||
Payload:
|
||||
MOV ESI,EAX ; payload start
|
||||
MOV CL,0x0A ; loop rep // attack // copy to the last .byte 0xcc
|
||||
SUB EDI,40+40+3 ; separation ( 40 from last movsd + 40 from new movsd + 3 extra)
|
||||
JNC Nocheck ; check limits
|
||||
MOV EDI,EBX
|
||||
Nocheck:
|
||||
MOV EAX,EDI
|
||||
REP MOVSD ; replicator
|
||||
JMP EAX
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
lea rsp, [0x25]
|
||||
mov rbx, qword[rsp]
|
||||
mov rcx, qword[rsp+8]
|
||||
mov r10, 0x25f
|
||||
mov r11, 0x3f0
|
||||
mov r12, 0x10
|
||||
|
||||
add rsp, r10
|
||||
and rsp, r11
|
||||
add rsp, r12
|
||||
push rcx
|
||||
push rbx
|
||||
jmp rsp
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
@@ -0,0 +1,38 @@
|
||||
; r2wars warrior by zutle
|
||||
; >> So you want to play the pusha game? :D
|
||||
;
|
||||
; The logic below generates the following code:
|
||||
;
|
||||
;
|
||||
;payload:
|
||||
; test sp, sp
|
||||
; jnz replicate
|
||||
; mov sp, 0x400
|
||||
;replicate:
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; mov [esp + 0xc], ecx
|
||||
; mov eax, esp
|
||||
; jmp eax
|
||||
|
||||
call start
|
||||
start:
|
||||
pop esp
|
||||
and esp, 0xffffff00
|
||||
add esp, 0x20
|
||||
mov edx, 0xe0ffe089
|
||||
mov ebx, 0x0c244c89
|
||||
mov ecx, 0x60606060
|
||||
mov ebp, 0x60606060
|
||||
mov esi, 0x0400bc66
|
||||
mov edi, 0x0475e485
|
||||
pushal
|
||||
mov [esp + 0xc], ecx
|
||||
mov eax, esp
|
||||
jmp eax
|
||||
@@ -0,0 +1,18 @@
|
||||
; This bot sucks but I wamted to make something
|
||||
mov esp, 0x3de
|
||||
mov edx, 0xdead
|
||||
mov ebx, 0xdead
|
||||
mov ecx, 0xdead
|
||||
jmp loop
|
||||
hijack:
|
||||
jmp eax
|
||||
loop:
|
||||
inc al
|
||||
cmp eax, 0x3de
|
||||
jle continue
|
||||
xor eax, eax
|
||||
continue:
|
||||
cmp [eax], 0x00
|
||||
jne hijack
|
||||
pushal
|
||||
jmp loop
|
||||
@@ -0,0 +1,19 @@
|
||||
call get_eip
|
||||
get_eip:
|
||||
pop esp
|
||||
sub ecx, 0x20
|
||||
dec eax
|
||||
|
||||
qq:
|
||||
|
||||
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
|
||||
add esp, ecx
|
||||
dec ecx
|
||||
cmp esp, 0x80
|
||||
ja qq
|
||||
mov esp, 0x3a0
|
||||
jmp qq
|
||||
@@ -0,0 +1,33 @@
|
||||
; her isimizde hayirlisi olsun
|
||||
; pushad loopunu 0x14 civarına unpack ettikten sonra
|
||||
; oraya ziplayip 0x400'den geriye pushad yapmaya baslar
|
||||
; v3: a longer pushad init
|
||||
pack:
|
||||
; mov edi, 0xcccccccc
|
||||
; mov esi, 0xcccccccc
|
||||
; mov ebp, 0xcccccccc
|
||||
mov ebx, 0x00000400
|
||||
mov edx, 0x6060dc89
|
||||
mov ecx, 0x60606060
|
||||
mov eax, 0xf6eb6060
|
||||
unpack:
|
||||
mov esp, 0x220
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
pushad
|
||||
add esp, 0x14 ; if shorter, tune this
|
||||
jmp esp
|
||||
@@ -0,0 +1,19 @@
|
||||
call init
|
||||
init:
|
||||
pop esp
|
||||
add esp, 0x26
|
||||
mov dword [eax], esp ; esp saved @0x0
|
||||
sub esp, 0x20
|
||||
save:
|
||||
popad
|
||||
jmp restore
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
restore:
|
||||
mov esp, dword [0x0]
|
||||
add esp, 0x20
|
||||
xor esi, esi
|
||||
mov dword [esi], esp
|
||||
pushad
|
||||
@@ -0,0 +1,15 @@
|
||||
mov eax, 0xc3c3c3c3
|
||||
mov ebx, 1024
|
||||
mov edx, 0xa0
|
||||
mov ebp, 0xe4ff6060
|
||||
mov esi, 0x606060e3
|
||||
mov edi, 0x420fd439
|
||||
call pwn
|
||||
pwn:
|
||||
pop esp
|
||||
sub esp,4
|
||||
pushad
|
||||
mov esp, 0x340
|
||||
pushad
|
||||
jmp esp
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Anisse Astier
|
||||
.arch arm
|
||||
.bits 32
|
||||
.hex 18d08fe2
|
||||
.hex ff5fbde8
|
||||
.hex 34d0b0e3
|
||||
.hex ff07ade8
|
||||
.hex f00fade8
|
||||
.hex 0f005ee1
|
||||
.hex 80d0a043
|
||||
.hex 44f0a043
|
||||
.hex 3fde0d42
|
||||
.hex ff1fad48
|
||||
.hex ff07ad48
|
||||
.hex f00fad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ecffff4a
|
||||
.hex 0100005f
|
||||
.hex ccc3ccc3
|
||||
@@ -0,0 +1,17 @@
|
||||
; when i say jump -- you say how high
|
||||
|
||||
mov eax, 0xffffffff
|
||||
mov ecx, eax
|
||||
mov edx, eax
|
||||
mov ebx, eax
|
||||
mov ebp, eax
|
||||
mov esi, eax
|
||||
|
||||
mov edi, 0x000
|
||||
mov esp, 0x400
|
||||
mov [edi], 0x20fc8360
|
||||
mov [edi+4], 0xff600374
|
||||
mov [edi+8], 0x0400bce7
|
||||
mov [edi+12], 0xe7ff0000
|
||||
;mov [edi], 0xe7ff6060
|
||||
jmp edi
|
||||
@@ -0,0 +1,18 @@
|
||||
sub x20, x20, 16;
|
||||
movk x21, 0x1ff;
|
||||
|
||||
bl start;
|
||||
start:
|
||||
movk x22, 0x8a;
|
||||
strb w22, [x30, 23]; // patch ORR -> AND
|
||||
ldp x0, x1, [x30, 16]; // copy
|
||||
ldp x2, x3, [x30, 32]; // copy
|
||||
|
||||
add x20, x20, 32;
|
||||
orr x20, x20, x21; // becomes AND
|
||||
stp x0, x1, [x20, 120]; // stomp
|
||||
stp x0, x1, [x20, 480]; // stomp
|
||||
stp x2, x3, [x20, 496]; // stomp
|
||||
stp x0, x1, [x20, 0]; // paste
|
||||
stp x2, x3, [x20, 16]; // paste
|
||||
br x20;
|
||||
@@ -0,0 +1,165 @@
|
||||
call init
|
||||
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
|
||||
init:
|
||||
mov eax, 0x340
|
||||
mov ebx, 0xc3c3c3c3
|
||||
mov ecx, ebx ; trash
|
||||
mov edx, 0x400 ; end of arena
|
||||
|
||||
mov edi, 0xd439c401
|
||||
mov esi, 0x60e04f0f
|
||||
mov ebp, 0xe4ff6060
|
||||
|
||||
call yolo_1
|
||||
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
|
||||
yolo_1:
|
||||
mov esp, 0x210
|
||||
pushad
|
||||
mov esp, 0x66
|
||||
pushad
|
||||
mov esp, 0x3f9
|
||||
pushad
|
||||
call yolo_2
|
||||
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
|
||||
yolo_2:
|
||||
mov esp, eax ; relocate to `eax`
|
||||
pushad
|
||||
pushad
|
||||
mov eax, 0x99 ; first address after reloc
|
||||
jmp esp
|
||||
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
@@ -0,0 +1,11 @@
|
||||
; kaploombaa
|
||||
.arch x86
|
||||
.bits 32
|
||||
mov eax, 0x00004000
|
||||
mov ebx, 0x0003fcff
|
||||
mov edi, 0x000070bc
|
||||
mov esi, 0x21c70100
|
||||
mov ebp, 0xe4ff60df
|
||||
mov esp, 0x40
|
||||
pushal
|
||||
jmp esp
|
||||
@@ -0,0 +1,30 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; bot for r2wars :: r2con2020 :: ;;
|
||||
; _goyo_ ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;.arch arm
|
||||
.bits 32
|
||||
|
||||
.hex 00D04FE2 ; SUB SP,R15,0x00
|
||||
.hex FF5FBDE8 ; POP {R0-R12,R14}
|
||||
|
||||
sp_top:
|
||||
.hex 050D5DE3 ; r0 CMP SP,0x140
|
||||
|
||||
top_from_subs:
|
||||
.hex FFFF2DA9 ; r1 PUSHGE {R0-R15}
|
||||
.hex FFFF2DA9 ; r2 PUSHGE {R0-R15}
|
||||
.hex FFFF2DA9 ; r3 PUSHGE {R0-R15}
|
||||
.hex FFFF2DA9 ; r4 PUSHGE {R0-R15}
|
||||
.hex FFFF2DA9 ; r5 PUSHGE {R0-R15}
|
||||
.hex 01DBA0D3 ; r6 MOVLE SP,0x400 ; time to go, sp low value
|
||||
.hex 0DF0A0C1 ; r7 MOVGT R15,SP ; if SP>0x140
|
||||
.hex FFFF2DE9 ; r8 PUSH {R0-R15} ; hole starting from 0x400
|
||||
.hex 28F05FE2 ; r9 SUBS R15,R15,0x28 ; clear flag for pushge
|
||||
.hex FFFFFFFF ; r10
|
||||
.hex cccccccc ; r11
|
||||
.hex F4F4F4F4 ; r12
|
||||
.hex 00feffff ; r14
|
||||
|
||||
|
||||
@@ -0,0 +1,490 @@
|
||||
; Warrior X86 32 bits by goyo.
|
||||
; Despues del RevientaViejas (r2con2018), viene: 'GORDASCO'
|
||||
; bot para r2wars (r2con2020)
|
||||
; Básicamente un replicator con problemas de peso
|
||||
|
||||
.bits 32
|
||||
Main:
|
||||
CALL Boot
|
||||
Boot:
|
||||
POP ESI
|
||||
JMP replicator
|
||||
# Esto para engordar el binario a 512 bytes y reducir el area de busqueda inicial del otro bot a 512.
|
||||
# Si es rápido podría encontrar al otro antes de que se mueva si es que se mueve.
|
||||
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
.byte 0xff
|
||||
|
||||
replicator:
|
||||
CLD
|
||||
MOV BX,0x3d7 ; memory top
|
||||
MOV EDI,ESI
|
||||
ADD SI,461 ; offset Payload - offset Main
|
||||
MOV EAX,ESI
|
||||
ADD EDI,40 ; only for 1st replication
|
||||
MOV [EDX],EAX ; Por si alguien se esconde en 0x0 o en 0x3ff y le pillo..
|
||||
MOV [EBX+36],EAX
|
||||
Payload:
|
||||
MOV ESI,EAX ; payload start
|
||||
MOV CL,0x0A ; loop rep // attack // copy to the last .byte 0xcc
|
||||
SUB EDI,40+40+3 ; separation ( 40 from last movsd + 40 from new movsd + 3 extra)
|
||||
JNC Nocheck ; check limits
|
||||
MOV EDI,EBX
|
||||
Nocheck:
|
||||
MOV EAX,EDI
|
||||
REP MOVSD ; replicator
|
||||
JMP EAX
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
.byte 0xcc
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
lea rsp, [0x25]
|
||||
mov rbx, qword[rsp]
|
||||
mov rcx, qword[rsp+8]
|
||||
mov r10, 0x25f
|
||||
mov r11, 0x3f0
|
||||
mov r12, 0x10
|
||||
|
||||
add rsp, r10
|
||||
and rsp, r11
|
||||
add rsp, r12
|
||||
push rcx
|
||||
push rbx
|
||||
jmp rsp
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
@@ -0,0 +1,8 @@
|
||||
dec rax
|
||||
mov rcx, 126
|
||||
mov rsp, 0x400
|
||||
mov rbx, 0xf3eb505050505050
|
||||
mov rdx, 0x5050505050ab48f3
|
||||
push rbx
|
||||
push rdx
|
||||
jmp rsp
|
||||
@@ -0,0 +1,38 @@
|
||||
; r2wars warrior by zutle
|
||||
; >> So you want to play the pusha game? :D
|
||||
;
|
||||
; The logic below generates the following code:
|
||||
;
|
||||
;
|
||||
;payload:
|
||||
; test sp, sp
|
||||
; jnz replicate
|
||||
; mov sp, 0x400
|
||||
;replicate:
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; pushal
|
||||
; mov [esp + 0xc], ecx
|
||||
; mov eax, esp
|
||||
; jmp eax
|
||||
|
||||
call start
|
||||
start:
|
||||
pop esp
|
||||
and esp, 0xffffff00
|
||||
add esp, 0x20
|
||||
mov edx, 0xe0ffe089
|
||||
mov ebx, 0x0c244c89
|
||||
mov ecx, 0x60606060
|
||||
mov ebp, 0x60606060
|
||||
mov esi, 0x0400bc66
|
||||
mov edi, 0x0475e485
|
||||
pushal
|
||||
mov [esp + 0xc], ecx
|
||||
mov eax, esp
|
||||
jmp eax
|
||||
@@ -0,0 +1,18 @@
|
||||
; This bot sucks but I wamted to make something
|
||||
mov esp, 0x3de
|
||||
mov edx, 0xdead
|
||||
mov ebx, 0xdead
|
||||
mov ecx, 0xdead
|
||||
jmp loop
|
||||
hijack:
|
||||
jmp eax
|
||||
loop:
|
||||
inc al
|
||||
cmp eax, 0x3de
|
||||
jle continue
|
||||
xor eax, eax
|
||||
continue:
|
||||
cmp [eax], 0x00
|
||||
jne hijack
|
||||
pushal
|
||||
jmp loop
|
||||
@@ -0,0 +1,16 @@
|
||||
mov esp, 0x3c8
|
||||
|
||||
mov ebx, 0x01606060
|
||||
mov edx, 0x664949cc
|
||||
mov ecx, 0x0080fc81
|
||||
mov eax, 0xbc66f277
|
||||
pushad
|
||||
mov dword ptr[esp+0x20],0xeceb0390
|
||||
|
||||
call get_eip
|
||||
get_eip:
|
||||
pop esp
|
||||
mov ecx, 0xFFFFFFe9
|
||||
|
||||
mov eax, 0x3b8
|
||||
jmp eax
|
||||
@@ -0,0 +1,19 @@
|
||||
; her isimizde hayirlisi olsun
|
||||
; pushad loopunu 0x14 civarına unpack ettikten sonra
|
||||
; oraya ziplayip 0x400'den geriye pushad yapmaya baslar
|
||||
; v3: a longer pushad init
|
||||
pack:
|
||||
mov edi, 0x00000280
|
||||
mov esi, 0x6060fc89
|
||||
mov ebp, 0x60606060
|
||||
; esp
|
||||
mov ebx, 0x60606060
|
||||
mov edx, 0x60606060
|
||||
mov ecx, 0x0400bc60
|
||||
mov eax, 0xeaeb0000
|
||||
unpack:
|
||||
mov esp, 0x020
|
||||
pushad
|
||||
mov dword [esp + 4 + 8], 0x60606060
|
||||
add esp, 0x4 ; if shorter, tune this
|
||||
jmp esp
|
||||
@@ -0,0 +1,50 @@
|
||||
; "her isimizde hayirlisi olsun"
|
||||
|
||||
; a replicator bot. This one unpacks it's main loop payload
|
||||
; around 0xc and jumps to there. In the loop, it first fills
|
||||
; upper half of the arena then bottom half of the arena using
|
||||
; pushad's.
|
||||
;
|
||||
; v1: initial; pushad from 0x400 through 0x0 result: 5 of 9
|
||||
; v2: I don't remember not competed
|
||||
; v3: a longer pushad sequence in init phase for quickscoping result: 5 of 13 && 8 of 14
|
||||
; v4: the longest packed loop using all registers for just tryin'. result: 10 of 15
|
||||
;
|
||||
;
|
||||
; pack contents are below
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; mov esp, edi
|
||||
; loop:
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; pushad
|
||||
; mov esp, 0x400
|
||||
; jmp loop
|
||||
|
||||
pack:
|
||||
mov edi, 0x00000280
|
||||
mov esi, 0x6060fc89
|
||||
mov ebp, 0x60606060
|
||||
; esp popped here as 0x20 (a bad instruction). must be corrected in unpack loop
|
||||
mov ebx, 0x60606060
|
||||
mov edx, 0x60606060
|
||||
mov ecx, 0x0400bc60
|
||||
mov eax, 0xeaeb0000
|
||||
unpack:
|
||||
mov esp, 0x020
|
||||
pushad
|
||||
mov dword [esp + 4 + 8], 0x60606060 ; fix popped esp value
|
||||
add esp, 0x4 ; tune this according to pack length
|
||||
jmp esp
|
||||
@@ -0,0 +1,19 @@
|
||||
call init
|
||||
init:
|
||||
pop esp
|
||||
add esp, 0x26
|
||||
mov dword [eax], esp ; esp saved @0x0
|
||||
sub esp, 0x20
|
||||
save:
|
||||
popad
|
||||
jmp restore
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
.hex 0xcccccccc
|
||||
restore:
|
||||
mov esp, dword [0x0]
|
||||
add esp, 0x20
|
||||
xor esi, esi
|
||||
mov dword [esi], esp
|
||||
pushad
|
||||
@@ -0,0 +1,18 @@
|
||||
mov eax, 0xc3c3c3c3
|
||||
mov ebx, 1024
|
||||
mov edx, 0x84
|
||||
mov ebp, eax
|
||||
mov esi, 0xe4ff5160
|
||||
mov edi, 0x606060e3
|
||||
mov ecx, 0x420fd439
|
||||
mov esp, 0xa8
|
||||
call pwn
|
||||
pwn:
|
||||
pop esp
|
||||
sub esp,4
|
||||
pusha
|
||||
mov esp, 0xa8
|
||||
pusha
|
||||
push ecx
|
||||
jmp esp
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Anisse Astier
|
||||
.arch arm
|
||||
.bits 32
|
||||
.hex 18d08fe2
|
||||
.hex ff5fbde8
|
||||
.hex 34d0b0e3
|
||||
.hex ff07ade8
|
||||
.hex f00fade8
|
||||
.hex 0f005ee1
|
||||
.hex 80d0a043
|
||||
.hex 44f0a043
|
||||
.hex 3fde0d42
|
||||
.hex ff1fad48
|
||||
.hex ff07ad48
|
||||
.hex f00fad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ffffad48
|
||||
.hex ecffff4a
|
||||
.hex 0100005f
|
||||
.hex ccc3ccc3
|
||||
@@ -0,0 +1,15 @@
|
||||
mov eax, 0xffffffff
|
||||
mov ecx, eax
|
||||
mov edx, eax
|
||||
mov ebx, eax
|
||||
mov ebp, eax
|
||||
mov esi, eax
|
||||
|
||||
mov edi, 0xd
|
||||
mov esp, 0x400
|
||||
mov [edi], 0x20fc8360
|
||||
mov [edi+4], 0xff600374
|
||||
mov [edi+8], 0x0400bce7
|
||||
mov [edi+12], 0xe7ff0000
|
||||
;mov [edi], 0xe7ff6060
|
||||
jmp edi
|
||||
@@ -0,0 +1,18 @@
|
||||
sub x20, x20, 16;
|
||||
movk x21, 0x1ff;
|
||||
|
||||
bl start;
|
||||
start:
|
||||
movk x22, 0x8a;
|
||||
strb w22, [x30, 23]; // patch ORR -> AND
|
||||
ldp x0, x1, [x30, 16]; // copy
|
||||
ldp x2, x3, [x30, 32]; // copy
|
||||
|
||||
add x20, x20, 32;
|
||||
orr x20, x20, x21; // becomes AND
|
||||
stp x0, x1, [x20, 120]; // stomp
|
||||
stp x0, x1, [x20, 480]; // stomp
|
||||
stp x2, x3, [x20, 496]; // stomp
|
||||
stp x0, x1, [x20, 0]; // paste
|
||||
stp x2, x3, [x20, 16]; // paste
|
||||
br x20;
|
||||
@@ -0,0 +1,165 @@
|
||||
call init
|
||||
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
|
||||
init:
|
||||
mov eax, 0x340
|
||||
mov ebx, 0xc3c3c3c3
|
||||
mov ecx, ebx ; trash
|
||||
mov edx, 0x400 ; end of arena
|
||||
|
||||
mov edi, 0xd439c401
|
||||
mov esi, 0x60e04f0f
|
||||
mov ebp, 0xe4ff6060
|
||||
|
||||
call yolo_1
|
||||
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
|
||||
yolo_1:
|
||||
mov esp, 0x210
|
||||
pushad
|
||||
mov esp, 0x66
|
||||
pushad
|
||||
mov esp, 0x3f9
|
||||
pushad
|
||||
call yolo_2
|
||||
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
|
||||
yolo_2:
|
||||
mov esp, eax ; relocate to `eax`
|
||||
pushad
|
||||
pushad
|
||||
mov eax, 0x99 ; first address after reloc
|
||||
jmp esp
|
||||
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
Loaded 100 of 210 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user