Skip to content

Commit

Permalink
Some Changes/Fixes & Added README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
gxosty committed Mar 8, 2024
1 parent 317d9b4 commit 4b59a6c
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 46 deletions.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# TunMode Android

TunMode is an Android project that routes traffic through a VPN to intercept packets. It supports TCP and UDP protocols and works on a semi-TCP stack, making it suitable for intercepting packets. You can also optionally intercept DNS queries or let the system resolve them. Essentially, TunMode acts as a proxy without editing or blocking any packets, allowing traffic to flow in and out seamlessly.

## Features

- Route traffic through a VPN to intercept packets
- Support for TCP and UDP protocols
- Optional DNS query interception
- Proxy-like functionality with transparent traffic flow

## Notes
* Might not work properly on Android 14 because of some API changes on that version. I am unable to test it.
* Doesn't support IPv6.

## Usage

1. [Download the TunMode APK](https://github.com/gxosty/TunMode/releases/latest)
2. Install the APK on your Android device
3. Open and click button in the center
4. Start intercepting packets and DNS queries as needed

### Prerequisites

- Android Studio
- Android SDK API Level 21 or higher
- Android NDK 25+ (maybe 24 is also ok, didn't test)

### Building the Project

1. Clone the repository
2. Open the project in Android Studio
3. Build and run the project on a connected Android device or emulator

## Contributing

We welcome contributions to TunMode! If you have any ideas, bug fixes, or feature enhancements, feel free to contribute by submitting a pull request. Please refer to the [contribution guidelines](CONTRIBUTING.md) for more information.
30 changes: 4 additions & 26 deletions app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.5)

set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_BUILD_TYPE Release)

if ((CMAKE_BUILD_TYPE STREQUAL "Release") OR (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel"))
add_definitions(-DRELEASE_MODE=1)
Expand All @@ -14,35 +14,14 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/src/internal)

if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
set(DPIMASK_LIBS_DIR "${CMAKE_SOURCE_DIR}/lib/armeabi-v7a")
set(TUNMODE_LIBS "${CMAKE_SOURCE_DIR}/lib/armeabi-v7a")
elseif (${ANDROID_ABI} STREQUAL "arm64-v8a")
set(DPIMASK_LIBS_DIR "${CMAKE_SOURCE_DIR}/lib/arm64-v8a")
set(TUNMODE_LIBS "${CMAKE_SOURCE_DIR}/lib/arm64-v8a")
else()
message(SEND_ERROR "Wrong ANDROID_ABI: ${ANDROID_ABI}")
endif()

link_directories(${DPIMASK_LIBS_DIR})

# add_library(crypto SHARED IMPORTED)
# set_target_properties(
# crypto
# PROPERTIES IMPORTED_LOCATION
# ${DPIMASK_LIBS_DIR}/libcrypto.so
# )

# add_library(ssl SHARED IMPORTED)
# set_target_properties(
# ssl
# PROPERTIES IMPORTED_LOCATION
# ${DPIMASK_LIBS_DIR}/libssl.so
# )

# add_library(curl SHARED IMPORTED)
# set_target_properties(
# curl
# PROPERTIES IMPORTED_LOCATION
# ${DPIMASK_LIBS_DIR}/libcurl.so
# )
link_directories(${TUNMODE_LIBS})

add_library(tunmode SHARED
main.cxx
Expand Down Expand Up @@ -74,5 +53,4 @@ add_library(tunmode SHARED
target_link_libraries(tunmode
log
android
z
)
2 changes: 1 addition & 1 deletion app/src/main/cpp/include/tunmode/common/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace tunmode
void operator()(const void* buffer, const size_t& size);

private:
char _buffer[TUNMODE_BUFFER_SIZE + 200];
char _buffer[TUNMODE_BUFFER_SIZE + 100];

void _copy(const void* buffer, const size_t& size);
};
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/cpp/include/tunmode/definitions.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#define TUNMODE_PACKET_SIZE 8192
#define TUNMODE_BUFFER_SIZE 8192
#define TUNMODE_PACKET_SIZE 1500
#define TUNMODE_BUFFER_SIZE 1500

#define TUNMODE_PROTOCOL_TCP 6
#define TUNMODE_PROTOCOL_UDP 17
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/include/tunmode/manager/udpmanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace tunmode
void handle_packet(const Packet& packet) override;

private:
Session* add(uintptr_t id) override;
Session* add(uint64_t id) override;

friend class UDPSession;
};
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/cpp/include/tunmode/socket/tcpsocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ namespace tunmode
int connect(Socket* skt);

size_t send_tun(Packet& packet) override;
size_t send(const Packet& packet) override;
size_t send(const Buffer& buffer) override;
size_t recv(Buffer& buffer) override;

Expand All @@ -68,6 +69,8 @@ namespace tunmode
in_addr server_addr;
u_short server_port;

bool syn_recved;

TCPVars vars;
TCPState state;

Expand Down
11 changes: 7 additions & 4 deletions app/src/main/cpp/main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ Java_git_gxosty_tunmode_interceptor_services_TunModeService_tunnelOpenNative(JNI
tunmode::params::dns_address.s_addr = 0;

const char* str_net_iface = env->GetStringUTFChars(net_iface, NULL);
const char* str_dns_address = env->GetStringUTFChars(dns_address, NULL);

struct ifreq ifr;
int if_fd = socket(AF_INET, SOCK_DGRAM, 0);
Expand All @@ -30,10 +29,14 @@ Java_git_gxosty_tunmode_interceptor_services_TunModeService_tunnelOpenNative(JNI
close(if_fd);
tunmode::params::net_iface = ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr;

inet_pton(AF_INET, str_dns_address, &tunmode::params::dns_address);

env->ReleaseStringUTFChars(net_iface, str_net_iface);
env->ReleaseStringUTFChars(dns_address, str_dns_address);

if (dns_address)
{
const char* str_dns_address = env->GetStringUTFChars(dns_address, NULL);
inet_pton(AF_INET, str_dns_address, &tunmode::params::dns_address);
env->ReleaseStringUTFChars(dns_address, str_dns_address);
}

tunmode::open_tunnel();
}
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/cpp/src/tunmode/socket/sessionsocket.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
#include <tunmode/definitions.hpp>

#include <unistd.h>
#include <fcntl.h>
#include <netinet/ip.h>

#include <misc/logger.hpp>

namespace tunmode
{
TunSocket* SessionSocket::tun = nullptr;
Expand All @@ -15,6 +18,7 @@ namespace tunmode
this->session_pipe[1] = 0;

pipe2(this->session_pipe, O_DIRECT);
// auto res = fcntl(this->session_pipe[1], F_SETPIPE_SZ, 16384);
}

SessionSocket::~SessionSocket()
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/cpp/src/tunmode/socket/socket.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,25 @@
#include <unistd.h>
#include <fcntl.h>

#include <misc/logger.hpp>

namespace tunmode
{
Socket::Socket(int domain, int type, int protocol) : closed{false}
{
LOGD_("Socket::Socket()");
this->socket = ::socket(domain, type, protocol);
}

Socket::Socket(int socket) : closed{false}
{
LOGD_("Socket::Socket()");
this->socket = socket;
}

Socket::~Socket()
{
LOGD_("Socket::~Socket()");
if (!this->closed)
::close(this->socket);
}
Expand Down
30 changes: 23 additions & 7 deletions app/src/main/cpp/src/tunmode/socket/tcpsocket.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
#include <cstdlib>
#include <random>

#include <misc/logger.hpp>

namespace tunmode
{
TCPSocket::TCPSocket() : SessionSocket()
{
this->state = TCPSTATE_LISTEN;
this->syn_recved = false;
}

TCPSocket::~TCPSocket()
Expand All @@ -27,16 +30,14 @@ namespace tunmode

int TCPSocket::connect(Socket* skt)
{
static constexpr char hs_opts[] = {2, 4, 31, 216, 1, 3, 3, 8, 1, 1, 4, 2};
static constexpr char hs_opts[] = {2, 4, 5, 180, 1, 3, 3, 8, 1, 1, 4, 2};

Packet client_packet;
client_packet.set_protocol(TUNMODE_PROTOCOL_TCP);
Packet server_packet;
server_packet.set_protocol(TUNMODE_PROTOCOL_TCP);

LOGD_("Getting SYN...");
*this > client_packet;
LOGD_("Got packet");

ip* ip_header;
tcphdr* tcp_header;
Expand Down Expand Up @@ -116,6 +117,24 @@ namespace tunmode
return SessionSocket::send_tun(packet);
}

size_t TCPSocket::send(const Packet& packet)
{
ip* ip_header;
tcphdr* tcp_header;
utils::point_headers_tcp((Packet*)&packet, &ip_header, &tcp_header);

if (tcp_header->th_flags == TH_SYN)
{
if (this->syn_recved)
{
return packet.get_size();
}
this->syn_recved = true;
}

return SessionSocket::send(packet);
}

size_t TCPSocket::send(const Buffer& buffer)
{
Packet packet;
Expand Down Expand Up @@ -188,13 +207,10 @@ namespace tunmode
}

buffer(in_buffer.get_buffer(), in_buffer.get_size());
LOGD_("Buffer size: %lu", buffer.get_size());
LOGD_("SEQ: %u", ntohl(tcp_header->th_seq));
this->vars.rcv.nxt += in_buffer.get_size();

if (tcp_header->th_flags != TH_ACK)
{
LOGD_("PSH -> Sending ACK");
Packet client_packet;
client_packet.set_protocol(TUNMODE_PROTOCOL_TCP);
ip* ip_header2;
Expand Down Expand Up @@ -229,7 +245,6 @@ namespace tunmode
}
else if (tcp_header->th_flags & TH_FIN)
{
LOGD_("FIN -> Sending ACK");
Packet client_packet;
client_packet.set_protocol(TUNMODE_PROTOCOL_TCP);
ip* ip_header2;
Expand Down Expand Up @@ -258,6 +273,7 @@ namespace tunmode
}
else
{
utils::print_packet_tcp(&packet);
this->reset(packet);
buffer.set_size(0);
return -1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@ public class TunModeService extends VpnService {
*
* Set dns resolver address (e.g. Google Public DNS 8.8.8.8)
*
* You may also set local imaginary fake IP address (e.g. 10.0.0.2)
* to route dns queries over TUN socket. Note that you will handle
* query packets yourself!
* You may also set fake IP address (e.g. 10.0.0.2)
* to route dns queries over TUN socket. Note that you
* will need to identify and handle query packets yourself!
*
* Set to `null` if you want to use system dns resolver
**/
public static final String dnsAddress = "8.8.8.8";
// public static final String dnsAddress = "8.8.8.8";
public static final String dnsAddress = null;

public static final String INTENT_EXTRA_OPERATION = "TunModeService_Operation";
public static final String NOTIFICATION_CHANNEL = "tun_mode_vpn_service_nc";
Expand Down Expand Up @@ -196,7 +197,7 @@ private void connect() {
VpnService.Builder builder = new VpnService.Builder()
.addAddress(TunModeService.tunAddress, 32)
.addRoute("0.0.0.0", 0)
.setMtu(8192);
.setMtu(1500);

if (TunModeService.dnsAddress != null) {
// route dns queries as well
Expand Down

0 comments on commit 4b59a6c

Please sign in to comment.