Code Monkey home page Code Monkey logo

ropgadget's People

Contributors

0xmirasio avatar allanlw avatar alvarofe avatar ambiso avatar aquynh avatar bensmrs avatar binyaminsharet avatar fdfalcon avatar fluxchief avatar hamarituc avatar jonathansalwan avatar kyle-kyle avatar mordak avatar mumbel avatar nename0 avatar nurmukhametov avatar oblique avatar penguin-wwy avatar pkubaj avatar ramikg avatar rekter0 avatar richo avatar rstenvi avatar sashs avatar sirusdv avatar sweetvishnya avatar tecknicaltom avatar yjugl avatar zachriggle avatar zku avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ropgadget's Issues

64 bit does not support looking for constant/wildcard gadgets

Currently only 32 bit supports looking for gadgets like:

add 0x?, %eax

To add this feature, the searcher will have to be modified to support looking for 64 bit values, and the script that generates the 64 bit gadgets will have to generate the wildcard gadgets as well.

/ROPgadget.py --binary /tmp/some_x86_win.dll --opcode '5c'

--opcode option total !@#$!@#$$$$$%@#$@$###

/ROPgadget.py --binary /tmp/some_x86_win_shit.dll --opcode '5c'

Traceback (most recent call last):
  File "./ROPgadget.py", line 17, in <module>
    ropgadget.main()
  File "/home/thistle/src/ROPgadget/ropgadget/__init__.py", line 28, in main
    sys.exit(Core(Args().getArgs()).analyze())
  File "/home/thistle/src/ROPgadget/ropgadget/core.py", line 174, in analyze
    elif self.__options.opcode:   return self.__lookingForOpcodes(self.__options.opcode)
  File "/home/thistle/src/ROPgadget/ropgadget/core.py", line 117, in __lookingForOpcodes
    allRef = [m.start() for m in re.finditer(opcodes.decode("hex"), section["opcodes"])]
  File "/usr/lib/python2.7/re.py", line 190, in finditer
    return _compile(pattern, flags).finditer(string)
  File "/usr/lib/python2.7/re.py", line 251, in _compile
    raise error, v # invalid expression
sre_constants.error: bogus escape (end of line)

Ugly as hell patch

allRef = [m.start() for m in re.finditer(opcodes.decode("hex").replace("\\","\\\\"), section["opcodes"])]

anyway --opcode don't work

ROPgadets ignores segment prefix when prints out the gadget list?

----Problem----:
For binary sequence 0x24 0x89 0x4b 0x64 0x33 0xc0 0x5b 0x8b 0xe5 0x5d 0xc3:
@ROPgadets gives a gadget:
and al, -0x77 ; dec ebx ; xor eax, eax ; pop ebx ; mov esp, ebp ; pop ebp ; ret

@gdb gives an other gadget:
and $0x89,%al; dec %ebx; fs; xor %eax,%eax; pop %ebx; mov %ebp,%esp; pop %ebp; ret

The difference is that result of ROPgadets ignores the segment prefix "fs" without a notice. Unfortunately, when i feed an emulator with this binary sequence, the emulator crashes.

---Question---
My question is could ROPgadets adds the prefixes if they exist. In this way, i will further process ROPgadets' output and filter out all gadgets with prefixes.

---Thanks---.

ROPgadget Doesn't Detect Mutli-Byte Ret

The following byte sequence is not recognized by ropgadget

c2 04 00        ret 4

By extension, all gadgets terminating with a multi-byte ret are also not recognized.

Here's an example:

$ ropgadget --binary ~/.wine/drive_c/windows/system32/notepad.exe
Gadgets information
============================================================

Unique gadgets found: 0
$ objdump -d ~/.wine/drive_c/windows/system32/notepad.exe
/home/user/.wine/drive_c/windows/system32/notepad.exe:     file format pei-x86-64
...
0000000010001000 <.text>:
    10001000:   b8 01 00 00 00          mov    $0x1,%eax
    10001005:   c2 04 00                retq   $0x4

I've uploaded a sample binary (notepad.exe from a Wine installation) here.

"False Positive"

It seems that every time you run the ROPgadget on some file the first gadget found is
pop %edi | ret
However this is not always(actually never in the programs i have tried) a valid gadget.
I have tried it on a few binaries. As an example, a simple hello world
ROPgadget -file ./a.out -g -> 0x080482c5: pop %edi | ret
objdump -d -M intel a.out -> 80482c5: 81 c3 6c 13 00 00 add ebx,0x136c
I haven't looked at the source code closely but it seems that it interprets some 'add' instructions as pop %edi | ret
Thanks and keep up the good workd :D

Support bin files

Being able to do something like this:
ROPGadget file -x86_32
and
ROPGadget file -x86_64

would be very useful. I often dump the content of executable memory but not always in an elf format. Being able to ROP the dump would be nice.

Wrong ROP gadget chain generated

Hello,

Thanks for this tool which works great so far except for one bug I had to fix in the generated ROP gadget chain.

In fact the problem is that the following ROP gadget is used to pop a value into %ecx :
p += pack("<I", off + 0x000d94d6) # pop %edx ; pop %ecx ; pop %ebx ; ret
p += "AAAA" # padding
p += pack("<I", off + 0x00143987) # @ .data + 7
p += "AAAA" # padding
But this does overwrite %ebx as well.
Then %ebx is not restored, leading to %ebx staying with the value 0x41414141 when the int $0x80 is called leading to a segmentation fault killing the process.

To fix this issue in the ROP chain I added the following gadget right after the previously described one :
p += pack("<I", off + 0x000d94d8) # pop %ebx ; ret
p += pack("<I", off + 0x00143980) # @ .data

I have tried to understand quickly the code to see if I could propose a patch to prevent ROPgadget tool to generate such a buggy ROP gadget chain, but unfortunately I don't have the time to do so, at least right now.

Here is the test case to reproduce the bug http://sionneau.net/ROPgadget/bug_report.tar.gz . This was generated on a Debian Squeeze 32 bits on VirtualBox.

Best regards,

Yann Sionneau

64bit elf!

bah without 64bit support this tool is useless. I guess I'm going back to objdump+grep.

Error: Architecture isn't supported

blah!

Support gadgets alignment option (x86)

Some platforms (like Chromᴏꜱ) enforce a jump alignment of 1 or several bytes (for examples on ɴaᴄl, the target address need to be dividable by 4)

What part of the code should be modified in order to enforce this requirement (because otherwise, if I jump to a non aligned address the program will segfault directly).

Error while processing static binaries

Hello!

There's an error when binary is for Linux and statically linked.
The program checks only for ELFOSABI_NONE and ELFOSABI_FREEBSD, but static binaries have OSABI=ELFOSABI_LINUX=3.

Quick fix:
check_arch_supported.c:

int check_arch_supported(void)
{
  if (pElf_Header->e_ident[EI_CLASS] == ELFCLASS32 && pElf_Header->e_machine == EM_386) {
    if (pElf_Header->e_ident[EI_OSABI] == ELFOSABI_NONE)
        return (0);
    if (pElf_Header->e_ident[EI_OSABI] == ELFOSABI_LINUX)
        return (0);
    if (pElf_Header->e_ident[EI_OSABI] == ELFOSABI_FREEBSD)
        return (0);
  }
  return (-1);
}

search_gadgets.c:
#define UNIX pElf_Header->e_ident[EI_OSABI] == ELFOSABI_NONE

define LINUX pElf_Header->e_ident[EI_OSABI] == ELFOSABI_LINUX

line 39: if (ELF_F && (UNIX || LINUX || FREEBSD) && PROC)

LSB MSB Mips

137         elif arch == CS_ARCH_MIPS:
138             gadgets = [
139                                #[b"\x09\xf8\x20\x03[\x00-\xff]{4}", 8, 4], # jrl $t9
140                                #[b"\x08\x00\x20\x03[\x00-\xff]{4}", 8, 4], # jr  $t9
141                                #[b"\x08\x00\xe0\x03[\x00-\xff]{4}", 8, 4]  # jr  $ra
142                                [b"\x03\xe0\x00\x08[\x00-\xff]{4}", 8, 4]  # jr  $ra
143                       ]
144             arch_mode += CS_MODE_BIG_ENDIAN # <- TODO

capstone.CsError: Different API version between core & binding (CS_ERR_VERSION)

$ python
Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import capstone
>>> capstone.version_bind()
(3, 0, 768)
vagrant@kali:/vagrant/ctfs/bostonkp2016$ ROPgadget --version
Version:        ROPgadget v5.4
Author:         Jonathan Salwan
Author page:    https://twitter.com/JonathanSalwan
Project page:   http://shell-storm.org/project/ROPgadget/
$ ROPgadget --binary ../x
Traceback (most recent call last):
  File "/usr/local/bin/ROPgadget", line 17, in <module>
    ropgadget.main()
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/__init__.py", line 28, in main
    sys.exit(Core(Args().getArgs()).analyze())
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/core.py", line 176, in analyze
    self.__getAllgadgets()
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/core.py", line 52, in __getAllgadgets
    if not self.__options.norop: self.__gadgets += G.addROPGadgets(section)
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/gadgets.py", line 118, in addROPGadgets
    return self.__gadgetsFinding(section, gadgets, arch, arch_mode)
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/gadgets.py", line 64, in __gadgetsFinding
    md = Cs(arch, mode)
  File "/usr/local/lib/python2.7/dist-packages/capstone/__init__.py", line 661, in __init__
    raise CsError(CS_ERR_VERSION)
capstone.CsError: Different API version between core & binding (CS_ERR_VERSION)

ROPGadget found wrong address

I'm not sure if I'm using the tool wrong or something else. Looking into the address provided by ROPGadget, the memory location actually contains completely different instructions. While the rp++ project gives the correct address->gadget mapping.

For example:
ROPGadget generates:

p += pack("<I", 0x0805d8f0) # xor eax,eax ; ret

While rp++ gives

0x0805d8f0: retn 0x0004 ;  (1 found)

Which matches the actual content in memory.

I can give a vagrant environment that can reproduce this bug if you want.

Segfault in src/search_gadgets.c:38

Segault reported by Bartlomiej

$ file ./ROPgadget
./ROPgadget: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
for GNU/Linux 2.6.15, dynamically linked (uses shared libs), not stripped

[maciek@SN4-WR1-wcss ~]$ ./ROPgadget /lib64/libc.so.6
Gadgets information
============================================================
Segmentation fault (core dumped)

Core was generated by `./ROPgadget /lib64/libc.so.6'.
Program terminated with signal 11, Segmentation fault.
#0  0x004c4233 in strlen () from /lib/libc.so.6
(gdb) bt
#0  0x004c4233 in strlen () from /lib/libc.so.6
#1  0x00495064 in vfprintf () from /lib/libc.so.6
#2  0x00495902 in buffered_vfprintf () from /lib/libc.so.6
#3  0x0049136d in vfprintf () from /lib/libc.so.6
#4  0x0053b9cb in __fprintf_chk () from /lib/libc.so.6
#5  0x0804a16d in fprintf (bin=0x990b008, gadgets=0x807e960,
NbGadFound=0xff8e04dc, NbTotalGadFound=0xff8e04d8) at
/usr/include/bits/stdio2.h:98
#6  check_gadget (bin=0x990b008, gadgets=0x807e960,
NbGadFound=0xff8e04dc, NbTotalGadFound=0xff8e04d8) at
src/search_gadgets.c:38
#7  find_all_gadgets (bin=0x990b008, gadgets=0x807e960,
NbGadFound=0xff8e04dc, NbTotalGadFound=0xff8e04d8) at
src/search_gadgets.c:125
#8  0x0804a47d in search_gadgets (bin=0x990b008) at src/search_gadgets.c:150
#9  0x08049489 in main (argc=2, argv=0xff8e05d4) at src/main.c:234

So it segfaults when 32-bit version run against 64-bit binary.

Intel sytax vs. ATT Syntax by default

I think it might be better if we used AT&T syntax by default. I think the linux user base that will be using ROPGadget will expect AT&T assembly by default. Perhaps this isn't true and I am simply too used to GCC and GNU as so please correct me if I am wrong.

Also obviously the user can change which one he is using so it isn't that big of a deal either way.

option asm not work

root@webserver:# rop -v
RopGadget - Ropgadget v4.0.1
Jonathan Salwan - twitter @JonathanSalwan
Allan Wirth - allanwirth.com
http://www.shell-storm.org
root@webserver:
# rop /usr/bin/gdb -g -asm "mov %ecx, %eax ; pop %ebx"
rop: unrecognized option '-g'
/tmp/ropgadget_M7e2Vk: Assembler messages:
/tmp/ropgadget_M7e2Vk:3: Error: operand type mismatch for `pop'
open: No such file or directory

i want to find add %esp 0xXXXX, pop reg1, pop reg2 instructions

but -asm option not work..

Generate optimal rop gadgets

                # execve /bin/sh generated by RopGadget v3.3
                p += pack("<I", 0x000e0096) # pop %edx | pop %ecx | pop %ebx | ret
                p += pack("<I", 0x42424242) # padding
                p += pack("<I", 0x00178020) # @ .data
                p += pack("<I", 0x42424242) # padding
                p += pack("<I", 0x000238df) # pop %eax | ret
                p += "/bin"
                p += pack("<I", 0x0006cc5a) # mov %eax,(%ecx) | ret
                p += pack("<I", 0x000e0096) # pop %edx | pop %ecx | pop %ebx | ret
                p += pack("<I", 0x42424242) # padding
                p += pack("<I", 0x00178024) # @ .data + 4
                p += pack("<I", 0x42424242) # padding
                p += pack("<I", 0x000238df) # pop %eax | ret

By moving one byte along the "pop %edx, pop %ecx, pop %ebx, ret" to just pop "%ecx, pop %ebx, ret" it will optimize the generated size.

FreeBSD x64 compilation

so far on freebsd I've only had to change a couple minor things. First is the #include for wait.h and second is the path to my python3 binary. However, I am still having an issue building.

I am using python3.3

gmake cleanall

gmake all

...build stuff...
gcc -W -Wall -Wextra -ansi -pedantic -D_BSD_SOURCE -D_POSIX_SOURCE -I./includes -I./libs/libpe -O2 -ggdb -std=c99 -c -o src/x86/common_ropmaker.o src/x86/common_ropmaker.c
gcc -W -Wall -Wextra -ansi -pedantic -D_BSD_SOURCE -D_POSIX_SOURCE -I./includes -I./libs/libpe -O2 -ggdb -std=c99 -c -o src/x86/common_asm.o src/x86/common_asm.c
src/x86/common_asm.c: In function 'make_temporary_file':
src/x86/common_asm.c:32: warning: implicit declaration of function 'mkstemp'
gcc -W -Wall -Wextra -ansi -pedantic -D_BSD_SOURCE -D_POSIX_SOURCE -I./includes -I./libs/libpe -O2 -ggdb -std=c99 -c -o src/x8632/combo_ropmaker.o src/x8632/combo_ropmaker.c
gcc -W -Wall -Wextra -ansi -pedantic -D_BSD_SOURCE -D_POSIX_SOURCE -I./includes -I./libs/libpe -O2 -ggdb -std=c99 -c -o src/x8632/gadgets.o src/x8632/gadgets.c
script/makex64gadgets.py > src/x8664/gadgets.c
Traceback (most recent call last):
File "script/makex64gadgets.py", line 142, in
RET = list(assemble(["ret"]))[0]
IndexError: list index out of range
gmake: *** [src/x8664/gadgets.c] Error 1

Incorrect disassembly for certain instructions due to interpretation as unsigned int

ROPgadget produces incorrect disassembly for certain instructions. For instance, the byte sequence
'ff75f8'(vaddr 0x77c2b3052 in advapi32.dll version 6.1.7600.16835; md5sum: 0c65fa8214d6f8378d1d3ba1ca46af0a) corresponds to 'push dword ptr [ebp - 8]' while ROPgadget interprets it as 'push dword ptr [ebp + 0xfffffff8]'. However, I'm not sure if it's an issue with ROPgadget or with capstone since even CEnigma(uses capstone too apparently) outputs latter. rasm2 outputs former instruction so it could be handled in ROPgadget.

x86 Gadgets Not Recognized

Your regexes are missing a few instruction styles. Specifically, these:

~/pwntools ❯❯❯ asm 'JMP DWORD PTR [ESP]'
ff2424
~/pwntools ❯❯❯ asm 'JMP DWORD PTR [ESP+1234]'
ffa424d2040000
~/pwntools ❯❯❯ asm 'JMP DWORD PTR [EBP]'
ff2505000000
~/pwntools ❯❯❯ asm 'JMP DWORD PTR [EBP+1234]'
ff25d7040000
~/pwntools ❯❯❯ asm 'CALL DWORD PTR [ESP]'
ff1424
~/pwntools ❯❯❯ asm 'CALL DWORD PTR [ESP+1]'
ff542401
~/pwntools ❯❯❯ asm 'CALL DWORD PTR [EBP]'
ff1505000000
~/pwntools ❯❯❯ asm 'CALL DWORD PTR [EBP+1]'
ff1506000000

Additionally, you use the set [\x00-\xff] in several places. This could be replaced with ..

NameError: global name 'CS_ARCH_SPARC' is not defined

when i get ropgadget from libc.so, this program crashed!
How do i fix this?

ubuntu@ubuntu:~/ROPgadget$ ROPgadget --thumb --binary ../libc.so |more
Traceback (most recent call last):
File "/usr/local/bin/ROPgadget", line 5, in
pkg_resources.run_script('ROPGadget==5.4', 'ROPgadget')
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 499, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 1235, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/ROPGadget-5.4-py2.7.egg/EGG-INFO/scripts/ROPgadget", line 17, in
ropgadget.main()
File "/usr/local/lib/python2.7/dist-packages/ROPGadget-5.4-py2.7.egg/ropgadget/init.py", line 28, in main
sys.exit(Core(Args().getArgs()).analyze())
File "/usr/local/lib/python2.7/dist-packages/ROPGadget-5.4-py2.7.egg/ropgadget/core.py", line 176, in analyze
self.__getAllgadgets()
File "/usr/local/lib/python2.7/dist-packages/ROPGadget-5.4-py2.7.egg/ropgadget/core.py", line 52, in __getAllgadgets
if not self.__options.norop: self.__gadgets += G.addROPGadgets(section)
File "/usr/local/lib/python2.7/dist-packages/ROPGadget-5.4-py2.7.egg/ropgadget/gadgets.py", line 98, in addROPGadgets
elif arch == CS_ARCH_SPARC:
NameError: global name 'CS_ARCH_SPARC' is not defined

Install failed on Centos7


Traceback (most recent call last):
File "/usr/bin/ROPgadget", line 4, in
import('pkg_resources').run_script('ROPGadget==5.5', 'ROPgadget')
File "/usr/lib/python2.7/site-packages/pkg_resources/init.py", line 719, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/site-packages/pkg_resources/init.py", line 1511, in run_script
exec(script_code, namespace, namespace)
File "/usr/lib/python2.7/site-packages/ROPGadget-5.5-py2.7.egg/EGG-INFO/scripts/ROPgadget", line 10, in

File "build/bdist.linux-x86_64/egg/ropgadget/init.py", line 10, in
#
File "build/bdist.linux-x86_64/egg/ropgadget/binary.py", line 9, in
File "build/bdist.linux-x86_64/egg/ropgadget/loaders/init.py", line 9, in
# See the README file for information on usage and redistribution.
File "build/bdist.linux-x86_64/egg/ropgadget/loaders/elf.py", line 9, in
File "/usr/lib/python2.7/site-packages/capstone/init.py", line 230, in
raise ImportError("ERROR: fail to load the dynamic library.")

ImportError: ERROR: fail to load the dynamic library.

I used pip install ropgadget to install, when I use ROPgadget -v it occured an error above, so I use you source to isntall,but the problem still exists.

windows x64 pe file imagebase analyze error

from pe,py:73
class IMAGE_OPTIONAL_HEADER64(Structure):
fields = [
("Magic", c_ushort),
("MajorLinkerVersion", c_ubyte),
("MinorLinkerVersion", c_ubyte),
("SizeOfCode", c_uint),
("SizeOfInitializedData", c_uint),
("SizeOfUninitializedData", c_uint),
("AddressOfEntryPoint", c_uint),
("BaseOfCode", c_uint),
("BaseOfData", c_uint),
("ImageBase", c_ulonglong),
("SectionAlignment", c_uint),
("FileAlignment", c_uint),
("MajorOperatingSystemVersion", c_ushort),
("MinorOperatingSystemVersion", c_ushort),
("MajorImageVersion", c_ushort),
("MinorImageVersion", c_ushort),
("MajorSubsystemVersion", c_ushort),
("MinorSubsystemVersion", c_ushort),
("Win32VersionValue", c_uint),
("SizeOfImage", c_uint),
("SizeOfHeaders", c_uint),
("CheckSum", c_uint),
("Subsystem", c_ushort),
("DllCharacteristics", c_ushort),
("SizeOfStackReserve", c_ulonglong),
("SizeOfStackCommit", c_ulonglong),
("SizeOfHeapReserve", c_ulonglong),
("SizeOfHeapCommit", c_ulonglong),
("LoaderFlags", c_uint),
("NumberOfRvaAndSizes", c_uint)

from windows.h
typedef struct _IMAGE_OPTIONAL_HEADER64 {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
ULONGLONG ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
ULONGLONG SizeOfStackReserve;
ULONGLONG SizeOfStackCommit;
ULONGLONG SizeOfHeapReserve;
ULONGLONG SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

so there have no BaseOfData in IMAGE_OPTIONAL_HEADER64

how it works

I want to learn how ROPgadget choose the gadgets when the use it to analyse a binary file.Are there any documents about ?

Problem showing gadgets in console

Hello!

First of all, I'm glad this project goes on :)
I was about to explain that I couldn't find gadgets, but the problem was another. Look:

$ ROPgadget.py --binary /bin/ls --console
(ROPgadget)> load
[+] Loading gadgets, please wait...
[+] Gadgets loaded !
(ROPgadget)> display
Gadgets information
============================================================
0x000000010000308a : adc eax, 0x89490000 ; fmul qword ptr [rax + 0xffffffffffffff89] ; ret
0x0000000100002245 : adc ecx, dword ptr [rax + 0xffffffffffffffff] ; ret
0x0000000100001e9f : add al, -0x7a ; add rax, r14 ; jmp rax
(...)

Unique gadgets found: 136
(ROPgadget)> search eax
0x000000010000308a : adc eax, 0x89490000 ; fmul qword ptr [rax + 0xffffffffffffff89] ; ret
(...)
0x00000001000020f5 : add eax, 0x33fe ; pop rbp ; jmp rax
0x0000000100004048 : add eax, 0x89480000 ; ret
0x0000000100001ea2 : add eax, esi ; jmp rax
0x00000001000022e1 : add ecx, eax ; jmp rcx

You can see that a chain of two items is found (without counting the ret), but if I change depth to 3 and execute a new search, those chains are not found.

(ROPgadget)> depth 3
[+] Depth updated. You have to reload gadgets
(ROPgadget)> search eax
(ROPgadget)> 

Am I doing something wrong? I'm using osx and I have installed RopGadget as explained in the github readme.

Thanks for your time :)

Crash during ELF parsing

Hello !
I found lot of bugs in the ELF parser of ROPGadget.

A malformed ELF file can crash the application or maybe more :) .

I will not list all bugs, because the source is the same : the fields of the ELF structure arn't checked, and a bad value can crash the program.

Theses files can reproduce bugs (there are the .png extension, but this is ELF files) :
ropgadget1
ropgadget2
ropgadget3

problems about snapshots in README

There are some snapshots in README, which have different length of memory address and different assembly syntax: AT&T and Intel.
The result of "ROPgadget" is in Intel grammer. How can I reset it to AT&T grammer? And is there an option to decide whether I show assembly sequence in AT&T or Intel?

Can't find the 'mov dword ptr [r32], r32' gadget

Hello,
I tried using ROPgadget v5.4 on a pretty standard test file with a buffer overflow and I keep getting a "Can't find the 'mov dword ptr [r32], r32' gadget" message when I try to generate the ropchain.

Anyone else have a similar problem?

Here's the binary, compiled as: gcc -m32 -ggdb -fno-stack-protector rop1.c -o rop1

include <string.h>

static char _not_used = "/bin/sh";
void vuln(char * src)
{
char buff[32];
strcpy(buff, src);
}
int main(int argc, char *_argv)
{
if(argc >= 2)
vuln(argv[1]);
return 0;
}

Here's the ROPgadget output, using the command-line input: ROPgadget --binary rop1 --ropchain

Gadgets information

0x0804866f : adc al, 0x41 ; ret
0x080483e0 : add al, 0x24 ; sub al, 0xa0 ; add al, 8 ; call eax
0x0804841d : add al, 0x24 ; sub al, 0xa0 ; add al, 8 ; call edx
0x0804841b : add al, 0xc7 ; add al, 0x24 ; sub al, 0xa0 ; add al, 8 ; call edx
0x08048448 : add al, 8 ; add ecx, ecx ; ret
0x080483e4 : add al, 8 ; call eax
0x08048421 : add al, 8 ; call edx
0x080483c8 : add al, 8 ; cmp eax, 6 ; ja 0x80483d7 ; ret
0x080484cf : add byte ptr [eax], al ; add byte ptr [eax], al ; leave ; ret
0x080484d0 : add byte ptr [eax], al ; add cl, cl ; ret
0x0804830c : add byte ptr [eax], al ; add esp, 8 ; pop ebx ; ret
0x080484d1 : add byte ptr [eax], al ; leave ; ret
0x0804866c : add cl, byte ptr [eax + 0xe] ; adc al, 0x41 ; ret
0x080484d2 : add cl, cl ; ret
0x08048668 : add eax, 0x2300e4e ; dec eax ; push cs ; adc al, 0x41 ; ret
0x08048445 : add eax, 0x804a02c ; add ecx, ecx ; ret
0x08048402 : add eax, edx ; sar eax, 1 ; jne 0x804840f ; ret
0x0804844a : add ecx, ecx ; ret
0x08048539 : add esp, 0x1c ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0804830e : add esp, 8 ; pop ebx ; ret
0x0804846a : and al, 0x10 ; lahf ; add al, 8 ; call eax
0x080483e1 : and al, 0x2c ; mov al, byte ptr [0xd0ff0804] ; leave ; ret
0x0804841e : and al, 0x2c ; mov al, byte ptr [0xd2ff0804] ; leave ; ret
0x0804841a : and al, 4 ; mov dword ptr [esp], 0x804a02c ; call edx
0x080482f4 : call 0x80483b6
0x080483e6 : call eax
0x08048423 : call edx
0x08048405 : clc ; jne 0x804840c ; ret
0x080483cb : clc ; push es ; ja 0x80483d4 ; ret
0x080483ca : cmp eax, 6 ; ja 0x80483d5 ; ret
0x0804866d : dec eax ; push cs ; adc al, 0x41 ; ret
0x08048494 : dec ecx ; ret
0x08048669 : dec esi ; push cs ; xor byte ptr [edx], al ; dec eax ; push cs ; adc al, 0x41 ; ret
0x08048538 : fild word ptr [ebx + 0x5e5b1cc4] ; pop edi ; pop ebp ; ret
0x080483dd : in al, dx ; sbb bh, al ; add al, 0x24 ; sub al, 0xa0 ; add al, 8 ; call eax
0x08048670 : inc ecx ; ret
0x080483cd : ja 0x80483d2 ; ret
0x08048406 : jne 0x804840b ; ret
0x08048537 : jne 0x8048521 ; add esp, 0x1c ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0804846c : lahf ; add al, 8 ; call eax
0x080483e8 : leave ; ret
0x0804853a : les ebx, ptr [ebx + ebx*2] ; pop esi ; pop edi ; pop ebp ; ret
0x0804830f : les ecx, ptr [eax] ; pop ebx ; ret
0x08048447 : mov al, byte ptr [0xc9010804] ; ret
0x080483e3 : mov al, byte ptr [0xd0ff0804] ; leave ; ret
0x08048420 : mov al, byte ptr [0xd2ff0804] ; leave ; ret
0x080483c7 : mov al, byte ptr [0xf8830804] ; push es ; ja 0x80483d8 ; ret
0x08048444 : mov byte ptr [0x804a02c], 1 ; leave ; ret
0x0804855f : mov dword ptr [0x8300001a], eax ; les ecx, ptr [eax] ; pop ebx ; ret
0x08048468 : mov dword ptr [esp], 0x8049f10 ; call eax
0x080483df : mov dword ptr [esp], 0x804a02c ; call eax
0x0804841c : mov dword ptr [esp], 0x804a02c ; call edx
0x080484ce : mov eax, 0 ; leave ; ret
0x080483b0 : mov ebx, dword ptr [esp] ; ret
0x080483af : nop ; mov ebx, dword ptr [esp] ; ret
0x080483ad : nop ; nop ; mov ebx, dword ptr [esp] ; ret
0x080483ab : nop ; nop ; nop ; mov ebx, dword ptr [esp] ; ret
0x08048548 : nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; ret
0x08048549 : nop ; nop ; nop ; nop ; nop ; nop ; nop ; ret
0x0804854a : nop ; nop ; nop ; nop ; nop ; nop ; ret
0x0804854b : nop ; nop ; nop ; nop ; nop ; ret
0x0804854c : nop ; nop ; nop ; nop ; ret
0x0804854d : nop ; nop ; nop ; ret
0x0804854e : nop ; nop ; ret
0x0804854f : nop ; ret
0x080483e5 : or bh, bh ; ror cl, 1 ; ret
0x08048422 : or bh, bh ; ror cl, cl ; ret
0x080483c9 : or byte ptr [ebx + 0x17706f8], al ; ret
0x08048449 : or byte ptr [ecx], al ; leave ; ret
0x08048401 : pop ds ; add eax, edx ; sar eax, 1 ; jne 0x8048410 ; ret
0x0804853f : pop ebp ; ret
0x0804853c : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x08048311 : pop ebx ; ret
0x0804853e : pop edi ; pop ebp ; ret
0x0804853d : pop esi ; pop edi ; pop ebp ; ret
0x0804866e : push cs ; adc al, 0x41 ; ret
0x0804866a : push cs ; xor byte ptr [edx], al ; dec eax ; push cs ; adc al, 0x41 ; ret
0x080484e5 : push ebx ; call 0x80483b7
0x080483cc : push es ; ja 0x80483d3 ; ret
0x080484e4 : push esi ; push ebx ; call 0x80483b8
0x08048403 : rcl cl, 1 ; clc ; jne 0x804840e ; ret
0x080482fa : ret
0x080483fe : ret 0xeac1
0x080483e7 : ror cl, 1 ; ret
0x08048424 : ror cl, cl ; ret
0x08048404 : sar eax, 1 ; jne 0x804840d ; ret
0x080483b1 : sbb al, 0x24 ; ret
0x0804853b : sbb al, 0x5b ; pop esi ; pop edi ; pop ebp ; ret
0x080483de : sbb bh, al ; add al, 0x24 ; sub al, 0xa0 ; add al, 8 ; call eax
0x080483ff : shr edx, 0x1f ; add eax, edx ; sar eax, 1 ; jne 0x8048412 ; ret
0x08048446 : sub al, 0xa0 ; add al, 8 ; add ecx, ecx ; ret
0x080483e2 : sub al, 0xa0 ; add al, 8 ; call eax
0x0804841f : sub al, 0xa0 ; add al, 8 ; call edx
0x080483c6 : sub al, 0xa0 ; add al, 8 ; cmp eax, 6 ; ja 0x80483d9 ; ret
0x080482f1 : sub esp, 8 ; call 0x80483b9
0x0804866b : xor byte ptr [edx], al ; dec eax ; push cs ; adc al, 0x41 ; ret

Unique gadgets found: 96

ROP chain generation

  • Step 1 -- Write-what-where gadgets

    [-] Can't find the 'mov dword ptr [r32], r32' gadget

Python2 vs python3

Lot of people send me an email because can't gen x8664/gadgets.c
I updated the Makefile to use genInstrX86.py with python2.

Undefined ref to tab_x8664

I've tried this on 4 different linux systems and get a similar error when I do the 'make':

/home/ron/ROPgadget/src/search_gadgets.c:150: undefined reference to tab_x8664' ./src/x86/common_ropmaker.o: In functionx86_ropmaker':
/home/ron/ROPgadget/src/x86/common_ropmaker.c:29: undefined reference to `tab_x8664'
collect2: ld returned 1 exit status
make: *** [ROPgadget] Error 1

ROPgadget Fails on pwnable.kr tiny_easy

Here is the 90-byte binary: https://drive.google.com/file/d/0B_3U7vX-2nJITC15NHBjbVVyaVU/view?usp=sharing

$ ROPgadget --version
Version:        ROPgadget v5.3
Author:         Jonathan Salwan
Author page:    https://twitter.com/JonathanSalwan
Project page:   http://shell-storm.org/project/ROPgadget/
$ ROPgadget --binary ./tiny_easy
Traceback (most recent call last):
  File "/home/user/.pyenv/versions/2.7.9/bin/ROPgadget", line 17, in <module>
    ropgadget.main()
  File "/home/user/.pyenv/versions/2.7.9/lib/python2.7/site-packages/ropgadget/__init__.py", line 21, in main
    sys.exit(Core(Args().getArgs()).analyze())
  File "/home/user/.pyenv/versions/2.7.9/lib/python2.7/site-packages/ropgadget/core.py", line 169, in analyze
    self.__binary = Binary(self.__options)
  File "/home/user/.pyenv/versions/2.7.9/lib/python2.7/site-packages/ropgadget/binary.py", line 37, in __init__
    self.__binary = ELF(self.__rawBinary)
  File "/home/user/.pyenv/versions/2.7.9/lib/python2.7/site-packages/ropgadget/loaders/elf.py", line 218, in __init__
    self.__setShdr()
  File "/home/user/.pyenv/versions/2.7.9/lib/python2.7/site-packages/ropgadget/loaders/elf.py", line 267, in __setShdr
    string_table = str(self.__binary[(self.__shdr_l[self.__ElfHeader.e_shstrndx].sh_offset):])
IndexError: list index out of range

offset should be honored

offset should be honored when generating ropchain for libs the data, data+4, data+8..etc uses the address from vaddr of the section without honoring "--offset".

Error missing gadget

We can see that this following gadget is missing "mov %eax,(%e?x)"
But we can find :

  1. 0x0003e208: mov DWORD PTR [edx],ecx ; ret

and

  1. 0x000daea3: pop ecx ; ret
  2. 0x00004f66: pop edx ; ret

Full dump below :

$ ROPgadget /lib32/libc.so.6
Gadgets information
============================================================
0x00002494: syscall
0x00003c52: dec edi ; ret
0x00003db6: dec esp ; ret
0x00004f66: pop edx ; ret
0x000054f7: xchg ebp,eax ; ret
0x000054f7: xchg ebp,eax ; ret
0x00006d5c: inc ebx ; ret
0x00006d7c: pop esp ; ret
0x0000dd24: nop ; ret
0x0001a3e3: pop ebp ; ret
0x0001acad: pop esi ; pop edi ; pop ebp ; ret
0x000256bd: pop ebx ; pop esi ; pop ebp ; ret
0x000264ec: pop eax ; ret
0x00026f8e: inc eax ; ret
0x0002daff: mov DWORD PTR [eax],ecx ; ret
0x0002daff: mov DWORD PTR [edi],edi ; ret
0x0002daff: mov DWORD PTR [ebx],esp ; ret
0x0002e605: int 0x80
0x0003b9c4: pop ebx ; pop esi ; pop edi ; ret
0x0003b9c6: pop edi ; ret
0x0003e12e: xor eax,eax ; ret
0x0003e208: mov DWORD PTR [edx],ecx ; ret
0x0003e5c8: pop ebp ; pop esi ; pop edi ; ret
0x0006e077: inc ebp ; ret
0x0007c890: pop ebx ; ret
0x0007dd20: mov ebx,DWORD PTR [esp] ; ret
0x0007e139: pop esi ; ret
0x0007e65f: mov esi,edx ; ret
0x00085604: mov eax,edx ; ret
0x0008d290: pop edi ; pop esi ; pop ebx ; ret
0x000a4f87: pop eax ; pop edi ; pop esi ; ret
0x000a5017: neg eax ; ret
0x000b19f7: mov eax,DWORD PTR [eax] ; ret
0x000b19f7: mov esp,DWORD PTR [ebx] ; ret
0x000b19f7: mov edi,DWORD PTR [edi] ; ret
0x000b3947: xchg ebx,eax ; ret
0x000b3947: xchg ebx,eax ; ret
0x000be07b: inc ecx ; ret
0x000c7a34: dec eax ; ret
0x000d0107: dec ebp ; ret
0x000daea3: pop ecx ; ret
0x000de012: mov ebx,edx ; ret
0x000e68ef: pop ebx ; pop edi ; pop ebp ; ret
0x000e8ca1: push ebp ; ret
0x000ee377: dec ebx ; ret
0x000f06cc: inc esp ; ret
0x000f0c1b: push ecx ; ret
0x000f325f: pop edx ; pop ecx ; pop eax ; ret
0x000fcf3b: pop esi ; pop ebx ; pop edx ; ret
0x000fcf66: pop edx ; pop ecx ; pop ebx ; ret
0x00105df4: bswap eax ; ret
0x0011108d: shr eax,1 ; ret
0x00119e09: xchg esp,eax ; ret
0x00119e09: xchg esp,eax ; ret
0x0012a2a9: push eax ; ret
0x0012a319: push esp ; ret
0x0012a6ca: mov ecx,DWORD PTR [esp] ; ret
0x0012a6ce: mov edx,DWORD PTR [esp] ; ret
0x001319e8: push edx ; ret
0x0013267d: pop esi ; pop edi ; pop ebx ; ret
0x00132be2: pop edi ; pop ebp ; pop ebx ; ret
0x00133ae7: inc edx ; ret
0x0014616d: pop esi ; pop ebp ; pop ebx ; ret
0x00148c93: mov eax,ecx ; ret
0x0015940e: push esi ; ret
0x001704fd: dec esi ; ret
0x00171c9d: inc edi ; ret
0x0017a073: xchg ecx,eax ; ret
0x0017a073: xchg ecx,eax ; ret
0x0017ce19: push edi ; ret
0x0017ed9f: dec edx ; ret
0x001825ea: dec ecx ; ret

Unique gadgets found: 72
This binary depends on shared libraries (you might want to check these):
    ld-linux.so.2


Possible combinations.
============================================================

    - .......... => mov %eax,(%e?x)
    - 0x000264ec => pop eax ; ret
    - 0x0007c890 => pop ebx ; ret
    - 0x000daea3 => pop ecx ; ret
    - 0x00004f66 => pop edx ; ret
    - 0x0003e12e => xor eax,eax ; ret
    - 0x00026f8e => inc eax ; ret
    - .......... => inc %ax
    - .......... => inc %al
    - 0x0002e605 => int 0x80
    - .......... => sysenter
    - 0x0001a3e3 => pop ebp ; ret
    - 0x00185ea0 => .data Addr
[-] Combo was not found.

ROPgadget is not working

After installing Capstone and Ropgadet using pip , it will not working . when i write ROPgadget system says that command not found.

Search all executable segments

Hi
Love your tool.

However, I am working on a challenge with a binary where all segments are executable. But it seems like only the .text segment is searched for gadgets. At least it doesn't find a 'call eax' opcode which is present in one of the data segments.

It would be nice, if all executable segments were searched.

A propos de ROPmaker

Bonjour,
nous sommes deux étudiants de Bordeaux en sécurité informatique et nous nous intéressons à votre logiciel dans le cadre d'un projet.
Nous avons une remarque à propos de l'option "-string" : le programme ne termine pas dans certains cas, notamment en utilisant un point d'interrogation dans la chaîne en entrée (comme -string "?" par exemple).
Nous pensons implémenter un algorithme de recherche de gadgets, si possible qui s'adaptera à plusieurs architectures (x86-32, x86-64, ARM,...), et l'ajouter à votre programme. Si cela vous intéresse, prenez contact avec nous, nous aurons sans doute d'autres questions à vous poser !
Cordialement.

Duplicate gadgets with slightly different disassembly

ROPgadget shows some gadgets multiple times.
It seems that this only affects jump instructions.

Details

Used DLL: msvcr71.dll - 7.10.3052.4 - md5: 69ba2b3eeeab52056e38fbecd4bc68ad

Gadgets affected:

VA: 2083931906
loopne 0x7c36470f ; or eax, edx ; ret
loopne 0x7c364710 ; or eax, edx ; ret

VA: 2083931900
jbe 0x7c36470a ; add eax, 0x40 ; shl eax, 8 ; or eax, edx ; ret
jbe 0x7c36470b ; add eax, 0x40 ; shl eax, 8 ; or eax, edx ; ret

VA: 2083931898
add byte ptr [eax], al ; jbe 0x7c36470c ; add eax, 0x40 ; shl eax, 8 ; or eax, edx ; ret
add byte ptr [eax], al ; jbe 0x7c36470d ; add eax, 0x40 ; shl eax, 8 ; or eax, edx ; ret

VA: 2083977953
je 0x7c36fab4 ; movzx edx, ax ; movzx eax, cx ; sub eax, edx ; pop esi ; ret
je 0x7c36fab6 ; movzx edx, ax ; movzx eax, cx ; sub eax, edx ; pop esi ; ret

VA: 2083977951
cmp ecx, eax ; je 0x7c36fab6 ; movzx edx, ax ; movzx eax, cx ; sub eax, edx ; pop esi ; ret
cmp ecx, eax ; je 0x7c36fab8 ; movzx edx, ax ; movzx eax, cx ; sub eax, edx ; pop esi ; ret

VA: 2083977950
cmp cx, ax ; je 0x7c36fab7 ; movzx edx, ax ; movzx eax, cx ; sub eax, edx ; pop esi ; ret
cmp cx, ax ; je 0x7c36fab9 ; movzx edx, ax ; movzx eax, cx ; sub eax, edx ; pop esi ; ret

Exception when ELF does not contain a string table

The following appears when trying to run on an ELF that has e_shstrndx = 0.

Traceback (most recent call last):
  File "ROPgadget.py", line 17, in <module>
    ropgadget.main()
  File "/Users/yifanlu/Downloads/ROPgadget-master/ropgadget/__init__.py", line 21, in main
    sys.exit(Core(Args().getArgs()).analyze())
  File "/Users/yifanlu/Downloads/ROPgadget-master/ropgadget/core.py", line 169, in analyze
    self.__binary = Binary(self.__options)
  File "/Users/yifanlu/Downloads/ROPgadget-master/ropgadget/binary.py", line 37, in __init__
    self.__binary = ELF(self.__rawBinary)
  File "/Users/yifanlu/Downloads/ROPgadget-master/ropgadget/loaders/elf.py", line 218, in __init__
    self.__setShdr()
  File "/Users/yifanlu/Downloads/ROPgadget-master/ropgadget/loaders/elf.py", line 267, in __setShdr
    string_table = str(self.__binary[(self.__shdr_l[self.__ElfHeader.e_shstrndx].sh_offset):])
IndexError: list index out of range

I fixed it by adding a if self.__ElfHeader.e_shstrndx: before the string table parsing in __setShdr

Bogus gadgets found and used for autoroping

After experimenting a lot and trying to wrap my mind around the issue, it still sounds like a bug. Apologies if im simply mistaken.
When roping based on ld-linux for instance, one gadget issued on my (x86) distro is:

0x0000e58a: pop edx ; jmp DWORD PTR [ebx]

Yet hexdump shows something different :

000e580: 0100 c683 3901 e475 870f **ff5a (pop edx indeed, then 0xff)** ffff 558b

And indeed gdb decodes bad instructions (exploitation leads to Illegal instruction crash as well):

(gdb) x/5i 0xb7fe3000+0x0000e58a
0xb7ff158a: pop    %edx
0xb7ff158b: (bad)  
0xb7ff158c: (bad)  
0xb7ff158d: decl   0x6d83c855(%ebx)
0xb7ff1593: rorb   0x6d(%ebx,%eax,4)

I did spot this kind of weird result for a couple of gadgets (event if most of them are correct). I will try and disect this asap.

ERROR: fail to load the dynamic library.

I am trying to run ROPgadget on osx and am getting the following errors after a successfull installation.

Traceback (most recent call last):
File "/usr/local/bin/ROPgadget", line 15, in
import ropgadget
File "/Library/Python/2.7/site-packages/ropgadget/init.py", line 14, in
import ropgadget.binary
File "/Library/Python/2.7/site-packages/ropgadget/binary.py", line 13, in
from ropgadget.loaders.elf import *
File "/Library/Python/2.7/site-packages/ropgadget/loaders/init.py", line 13, in
import ropgadget.loaders.elf
File "/Library/Python/2.7/site-packages/ropgadget/loaders/elf.py", line 13, in
from capstone import *
File "/Library/Python/2.7/site-packages/capstone/init.py", line 230, in
raise ImportError("ERROR: fail to load the dynamic library.")
ImportError: ERROR: fail to load the dynamic library.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.