< Return to Video

Console Hacking

  • 0:00 - 0:10
    32C3 preroll music
  • 0:10 - 0:16
    Herald: Okay, welcome to our
    last talk in this hall today!
  • 0:16 - 0:20
    It’s about Console Hacking and I guess
    that’s the reason why you are here.
  • 0:20 - 0:24
    Console hacking has a long
    tradition at our great conference
  • 0:24 - 0:30
    and we have seen lots of funny things.
    People doing stuff with Xboxes,
  • 0:30 - 0:34
    Playstations and everything.
  • 0:34 - 0:39
    Okay. Today we got a team which
    deals with the Nintendo DS,
  • 0:39 - 0:44
    so give a warm applause
    for plutoo, derrek and smea!
  • 0:44 - 0:54
    applause
  • 0:54 - 0:59
    smea: Hi! I’m smea,
    this is plutoo, this is derrek,
  • 0:59 - 1:03
    and today we are going to talk to you
    about our work on the Nintendo 3DS.
  • 1:03 - 1:05
    So, the way this talk is going to be
    structured, is we are just going to
  • 1:05 - 1:09
    go over all the hardware,
    organisation, software, like…
  • 1:09 - 1:12
    Just give you a basic overview
    about how the system works.
  • 1:12 - 1:15
    And after that we are going to go into
  • 1:15 - 1:18
    basically every layer of
    security the system has,
  • 1:18 - 1:21
    and break every one of them.
  • 1:21 - 1:23
    laughter
  • 1:23 - 1:28
    applause
  • 1:28 - 1:32
    Okay. So, as you probably know,
    the 3DS, the original Nintendo 3DS
  • 1:32 - 1:36
    was released in 2011. It’s a system
    that is kind of underpowered.
  • 1:36 - 1:41
    It’s got, like… It’s got an
    ARM11 dual core CPU,
  • 1:41 - 1:46
    268Mhz, it’s got a nice
    proprietary GPU, a bit of RAM,
  • 1:46 - 1:50
    you know, the usual. It’s also backwards
    compatible with the DS games,
  • 1:50 - 1:55
    which is nice. Then the new 3DS
    was released in 2014 and 2015,
  • 1:55 - 2:01
    there was like different regions. And it
    was basically just the same console,
  • 2:01 - 2:04
    just some improvements in the
    hardware. You’ve got a better CPU,
  • 2:04 - 2:09
    it has got more cores. It’s faster, it has
    got more RAM. Basically everywhere.
  • 2:09 - 2:12
    So, it is just the same thing,
    it runs the same software, exactly.
  • 2:12 - 2:16
    It has got some exclusive
    software, but not much.
  • 2:16 - 2:19
    So, in terms of a hardware overview, this
    is what what we are going to talk about
  • 2:19 - 2:24
    looks like; in general. So you
    got the top part right here,
  • 2:24 - 2:27
    which is what we are
    going to go into first.
  • 2:27 - 2:31
    This is like the ARM11 part.
  • 2:31 - 2:35
    Basically, you’ve got the ARM11,
    which is the main CPU. It runs
  • 2:35 - 2:41
    the main operating system. It has
    2 cores as I just said, or 4 cores.
  • 2:41 - 2:43
    So, it runs the main operating
    system, it runs the games,
  • 2:43 - 2:45
    it runs all the applications.
    Basically, it’s just –
  • 2:45 - 2:48
    if you’re doing something on the 3DS
    that you can… you can see it happening,
  • 2:48 - 2:52
    it’s happening on that CPU. It has got
    access to all of the main memory.
  • 2:52 - 2:56
    So that includes FCRAM,
  • 2:56 - 3:01
    which is 128MB or 256MB,
  • 3:01 - 3:05
    depending on which model it is.
    And FCRAM is actually divided
  • 3:05 - 3:09
    into 3 separate regions. So you
    first got the Application Region,
  • 3:09 - 3:13
    which contains the currently
    running game or application.
  • 3:13 - 3:17
    The System Region, which contains applets,
    which are basically tiny applications,
  • 3:17 - 3:20
    which run in the background.
    So, that includes the home menu,
  • 3:20 - 3:23
    which is actually always running
    in background, and the web browser,
  • 3:23 - 3:26
    which you can actually run at
    the same time as your game, so
  • 3:26 - 3:29
    it has to run there. And then you got the
    Base Region, which is more interesting.
  • 3:29 - 3:31
    It contains all the system modules
    of the operating system,
  • 3:31 - 3:35
    as well as some kernel data,
    such as handle tables
  • 3:35 - 3:40
    and MMU tables. So it is kind of sensitive
    stuff. And then we got a WRAM,
  • 3:40 - 3:44
    which is tiny and contains all
    the kernel code, and, well,
  • 3:44 - 3:50
    most of the kernel structures as well.
    So it’s also an interesting target.
  • 3:50 - 3:55
    Then we’ve got the lower part, which
    is the ARM9 part of the hardware.
  • 3:55 - 3:58
    So the ARM9 is basically a separate, well…
  • 3:58 - 4:03
    it’s an entirely separate CPU,
    which has access to…
  • 4:03 - 4:07
    well… So it runs basically the
    same microkernel as the ARM11.
  • 4:07 - 4:12
    It’s mostly the same code,
    it has just got some pure features.
  • 4:12 - 4:15
    Mostly it runs a single process,
    which is called ‘Process9’,
  • 4:15 - 4:19
    which does everything the ARM9 does.
    Beyond that the role of the ARM9 is
  • 4:19 - 4:24
    to broker access to hardware that
    might be sensitive in terms of security.
  • 4:24 - 4:29
    So one of the things it does is it
    brokers access to all storage media,
  • 4:29 - 4:34
    so that includes the permanent
    storage as well as the SD card.
  • 4:34 - 4:38
    And then it does all sorts of crypto
    stuff, which is really important,
  • 4:38 - 4:44
    and does that by using hardware, actually.
    So there is this hardware key scrambler,
  • 4:44 - 4:48
    which is used to.. to store
    secrets in hardware basically.
  • 4:48 - 4:51
    The idea is, you feed
    it two separate keys,
  • 4:51 - 4:55
    and it is going to generate a
    normal key and feed that directly
  • 4:55 - 4:59
    into the hardware implementation
    of the AES algorithm.
  • 4:59 - 5:02
    So that way, we never
    actually see the final keys.
  • 5:02 - 5:06
    So that’s something that
    is kind of annoying.
  • 5:06 - 5:10
    And then beyond that what you can see is:
    the ARM9 has access to all of main memory
  • 5:10 - 5:14
    without much of, well, without any
    restrictions. But it has also got
  • 5:14 - 5:18
    its own internal memory which the
    ARM11 does not have access to.
  • 5:18 - 5:21
    So the ARM9 internal memory is
    where the ARM9 stores all its code,
  • 5:21 - 5:27
    all of its data; and this way we
    can’t actually take over the ARM9
  • 5:27 - 5:33
    just from the ARM11 without some kind of
    exploit. So it’s basically a security CPU.
  • 5:33 - 5:37
    So this leads us to having
    4 layers of security.
  • 5:37 - 5:40
    Basically, you’re first going to have
    the ARM11 userland, which is what…
  • 5:40 - 5:44
    well, like your games, your applications,
    whatever. On top of that,
  • 5:44 - 5:49
    you’re going to have, well, below
    that, I guess, the ARM11 kernel.
  • 5:49 - 5:52
    So that is going to have
    full privileges on the ARM11.
  • 5:52 - 5:55
    And then you’re going to have
    ARM9 userland, which is ‘Process9’.
  • 5:55 - 6:00
    Beyond that you’ll have ARM9
    kernel mode. So that’s in theory.
  • 6:00 - 6:04
    In practice, the microkernel
    has a system call,
  • 6:04 - 6:09
    which we call… syscall…
    we call it ‘svc backdoor’.
  • 6:09 - 6:14
    Because essentially you feed it a
    function pointer and it just executes
  • 6:14 - 6:17
    that function in kernel mode.
    So you don’t even need an exploit
  • 6:17 - 6:21
    if you have access to that syscall.
    Of course, on the ARM11
  • 6:21 - 6:25
    no application or title or anything
    ever has access to that,
  • 6:25 - 6:30
    but on the ARM9 ‘Process9’ actually
    has access to it. Which means,
  • 6:30 - 6:34
    that from here we actually…
    well, userland and kernel mode
  • 6:34 - 6:38
    are basically the same thing.
    When you got userland on the ARM9,
  • 6:38 - 6:41
    you got kernel mode.
    So that’s nice.
  • 6:41 - 6:45
    Beyond that, in terms of
    cryptography on the system,
  • 6:45 - 6:49
    basically, they went out loud (?). So, anything
    that can be signed, is signed.
  • 6:49 - 6:52
    So, that includes the firmware,
    that includes every application.
  • 6:52 - 6:55
    Signatures are checked not only
    at install time but also at runtime,
  • 6:55 - 6:59
    so that’s something to keep in mind.
  • 6:59 - 7:03
    Same thing: anything that can
    be encrypted is encrypted.
  • 7:03 - 7:08
    And anything that can be made, well,
    console-specific through cryptography
  • 7:08 - 7:13
    or authentication, such as
    internal permanent storage
  • 7:13 - 7:18
    or the data that is stored on
    the SD card, or savegames,
  • 7:18 - 7:23
    or extra data for games, this
    is all made console-specific.
  • 7:23 - 7:27
    And gamecard-specific in
    regards of savegames.
  • 7:27 - 7:31
    So, that’s kind of annoying as well. And,
    of course, all this is handled by the ARM9
  • 7:31 - 7:36
    using the hardware… the crypto
    hardware, so we got to get through that
  • 7:36 - 7:38
    if we want to do interesting things.
  • 7:38 - 7:44
    So, first we are going to go through the
    first layer, which is the ARM11 userland.
  • 7:44 - 7:47
    Basically, getting a full
    hold onto the system.
  • 7:47 - 7:51
    So, we first need to find
    some kind of entry point.
  • 7:51 - 7:56
    There are problems… well,
    there are challenges there.
  • 7:56 - 8:00
    One of the challenges is
    that the system implements
  • 8:00 - 8:05
    strict Data Execution Prevention. So,
    existing pages will never be read…
  • 8:05 - 8:09
    well, will never be read-write-executable.
    It’s all only going to be read-only,
  • 8:09 - 8:13
    or read-writable or read-executable.
    There’s no way from a standard application
  • 8:13 - 8:18
    to reprotect or map new pages
    that are read-write-executable.
  • 8:18 - 8:22
    Because all of the system
    calls are locked out, except for
  • 8:22 - 8:26
    higher privileged system
    modules. Another thing is
  • 8:26 - 8:30
    that there is no ASLR, so that is not
    a challenge, that’s actually kind of nice.
  • 8:30 - 8:34
    The nice thing here is that we… well,
    that makes savegame vulnerabilities
  • 8:34 - 8:37
    totally fair game because, well, we don’t
    need an actual scripting environment
  • 8:37 - 8:41
    or any kind of exotic
    vulnerability to exploit this.
  • 8:41 - 8:45
    As long as we can get past
    DEP somehow. And then,
  • 8:45 - 8:49
    of course, the fact that all
    savegames are both encrypted
  • 8:49 - 8:53
    and made specific either to the
    gamecard or the game console,
  • 8:53 - 8:58
    in the case of eShop games, is really
    annoying for savegame vulnerabilities
  • 8:58 - 9:01
    because basically you can’t use those
    as an initial entry point in most cases,
  • 9:01 - 9:05
    because, well, you can’t generate
    the right, well, ES MAC,
  • 9:05 - 9:12
    or just… you don’t know the right
    cryptography. So, that’s annoying.
  • 9:12 - 9:15
    Thankfully, the 3DS runs Webkit…
  • 9:15 - 9:18
    laughter
  • 9:18 - 9:22
    So, that’s nice.
    Can always use that.
  • 9:22 - 9:26
    applause
  • 9:26 - 9:30
    So, Webkit is used in a number of places,
    obviously it’s using the main web browser,
  • 9:30 - 9:33
    which you can access from the home menu.
    It’s also used in the Youtube application,
  • 9:33 - 9:37
    which is available free on the eShop
    and doesn’t use any kind of
  • 9:37 - 9:41
    client side authentication for the server,
    so you can just redirect traffic through,
  • 9:41 - 9:47
    like a DNS server for example. Miiverse
    applet, other stuff, that also uses it.
  • 9:47 - 9:51
    Slightly more secure, but might be
    usable at some point, I don’t know.
  • 9:51 - 9:55
    Anywho, the important part here,
    is that it’s not only using webkit,
  • 9:55 - 9:59
    it is using a very old version of webkit.
    Basically, they do cherrypick
  • 9:59 - 10:03
    some patches into the version
    of webkit they use, but only
  • 10:03 - 10:10
    after we exploit those on release, so it
    comes a little too late, most of the time.
  • 10:10 - 10:16
    So yeah, this has been used by multiple
    people, most notably yellows8,
  • 10:16 - 10:22
    but it has proven to be a very
    efficient, reliable entry point.
  • 10:22 - 10:26
    Beyond that, we got Cubic Ninja as initial
    entry point. Cubic Ninja is a game
  • 10:26 - 10:30
    that was released in 2011 on Nintendo
    3DS. It is nice, because it actually
  • 10:30 - 10:34
    allows users to share levels
    that they make themselves
  • 10:34 - 10:41
    through QR codes; and also it is
    really bad at parsing those levels.
  • 10:41 - 10:45
    So what you can do, is just, well,
    manufacture your own QR code
  • 10:45 - 10:48
    that is going to crash the game
    and give you access. So these are
  • 10:48 - 10:53
    nice initial entry points. So, once we’ve
    got this, what we have to remember is
  • 10:53 - 10:56
    that we might be able to crash the game
    and may be able to control registers,
  • 10:56 - 11:01
    but we don’t actually have our code
    running because of that. So,
  • 11:01 - 11:04
    the obvious solution to
    hit this, is to use ROP.
  • 11:04 - 11:08
    For those of you, who are
    not familiar with ROP:
  • 11:08 - 11:12
    You build your own fake stack
    that lets you return into
  • 11:12 - 11:16
    code snippets that are located right
    before return instructions. That way…
  • 11:16 - 11:21
    so this is an example. You can just
  • 11:21 - 11:25
    jump to this kind of instruction,
    so ‘pop {r0, pc}’ and then
  • 11:25 - 11:29
    this is going to let you load your own
    register value and then it is going to
  • 11:29 - 11:34
    jump to the next instruction that you give
    it. So, this is a way of executing code
  • 11:34 - 11:38
    without actually executing code,
    which is widely used; so this is like
  • 11:38 - 11:42
    the obvious thing to do. Of course,
    ROP is annoying. It is very limiting.
  • 11:42 - 11:48
    It can be enough to actually execute
    an exploit to get higher privileges,
  • 11:48 - 11:53
    but overall it is just annoying and very
    limiting for homebrew, for example.
  • 11:53 - 11:56
    And of course, as I mentioned earlier, we
    don’t have access to any of the system calls
  • 11:56 - 12:01
    that would let us map
    read-writable-executable pages.
  • 12:01 - 12:05
    Also, the system does support dynamically
    linked libraries, so that might be a way,
  • 12:05 - 12:10
    but these are signed and checked in
    places that we can’t access at this point.
  • 12:10 - 12:14
    So, what we’re going to look
    at next is the GPU to see
  • 12:14 - 12:19
    if we use that to bypass that.
    What you can see here is that
  • 12:19 - 12:23
    the GPU has access not only to
    video RAM, but also to FCRAM,
  • 12:23 - 12:26
    which is, if you recall it, main
    memory. So, if you look at this,
  • 12:26 - 12:31
    with all the different memory regions,
  • 12:31 - 12:33
    we have got the Application Region
    here, which is entirely contained within
  • 12:33 - 12:39
    what the GPU can access within FCRAM.
    Of course, the GPU can not actually access
  • 12:39 - 12:43
    all of that FCRAM, so that is kind
    of limiting. What we can see here,
  • 12:43 - 12:49
    is that, of course, application code is
    within range of the GPU’s level of access.
  • 12:49 - 12:53
    The reason the GPU has access to
    FCRAM and Video RAM, through DMA,
  • 12:53 - 12:58
    by the way, is, so that it can access
    information such as textures,
  • 12:58 - 13:01
    vertex buffers, this sort of thing.
  • 13:01 - 13:04
    So, it’s actually kind of important. And
    the reason it can write to it is because
  • 13:04 - 13:09
    it has to render its data somewhere.
    The point is, that we can use this
  • 13:09 - 13:12
    to render data into main memory.
  • 13:12 - 13:16
    And main memory contains application
    code. And since the physical layout is
  • 13:16 - 13:20
    actually completely deterministic, and
    even if it wasn’t, we could just use the
  • 13:20 - 13:24
    read capabilities of the GPU to
    search for what we are looking for.
  • 13:24 - 13:28
    Well, we can use this to overwrite our
    current application’s text section
  • 13:28 - 13:33
    and we get code execution
    that way, in spite of DEP.
  • 13:33 - 13:34
    Yeah, so this is where
    we get code execution…
  • 13:34 - 13:35
    applause
  • 13:35 - 13:38
    We execute our own,
    unsigned code, which is very…
  • 13:38 - 13:40
    applause
  • 13:40 - 13:45
    It’s great, but we are still confined
    within the application sandbox.
  • 13:45 - 13:47
    So, we bypassed DEP,
    we are inside the sandbox.
  • 13:47 - 13:53
    This means we can only access
    our current application’s savedata,
  • 13:53 - 13:58
    so if we want to install some kind of
    secondary exploit, this is too limiting.
  • 13:58 - 14:02
    We can only access certain services and
    system calls, which is also limiting
  • 14:02 - 14:06
    and frustrating. And we can’t alter
    memory layout, so we can’t allocate
  • 14:06 - 14:09
    more executable pages
    than I mentioned earlier.
  • 14:09 - 14:11
    So, we are still kind
    of limited at this point.
  • 14:11 - 14:15
    So, what we are going to do, is look at
    what else the GPU can access.
  • 14:15 - 14:19
    And you can see, is that, of course, there
    is this entirely separate memory region
  • 14:19 - 14:22
    the GPU can modify.
  • 14:22 - 14:25
    So it can access most of the System
    Region. And the System Region contains
  • 14:25 - 14:28
    a few things. It contains the home menu, as
    I mentioned, because that is an applet.
  • 14:28 - 14:32
    It contains the internet browser, and it
    contains actually a single system module,
  • 14:32 - 14:38
    which is called ‘NS’, which we think stands
    for ‘Nintendo Shell’, we don’t really know.
  • 14:38 - 14:43
    So, let’s look at this. First we got
    NS code well beyond the GPU cutoff.
  • 14:43 - 14:46
    We got menu code, which is
    also well beyond GPU cutoff.
  • 14:46 - 14:51
    But we got the menu’s heap, right here,
    well, actually there is separate heaps,
  • 14:51 - 14:55
    these are well within the
    GPU’s range, so that’s good.
  • 14:55 - 15:00
    NS unfortunately is still well beyond the
    cutoff. All of its data, all of its code.
  • 15:00 - 15:03
    So we apparently can’t get to that.
  • 15:03 - 15:08
    So, then the idea is, to just,
    well, okay, so actually…
  • 15:08 - 15:11
    What’s interesting here, is that
    the cutoff is right before the end of
  • 15:11 - 15:14
    the System Region, which as we just
    saw, has some interesting things, but
  • 15:14 - 15:19
    also excludes all of Base Region,
    which also has very interesting things.
  • 15:19 - 15:24
    So, it seems likely that Nintendo knew
    about the capabilities of GPU DMA,
  • 15:24 - 15:27
    like the theoretical capabilities, but
    they didn’t do anything about it.
  • 15:27 - 15:31
    So, it seems that they probably didn’t
    realize what we could do with it,
  • 15:31 - 15:33
    which is a lot.
  • 15:33 - 15:38
    So, basically, we got menu heaps. So
    what we do, is… we have a heap, and
  • 15:38 - 15:42
    this is all C++ code. We are just
    going to find objects inside the heap
  • 15:42 - 15:47
    and overwrite it. So it’s pretty simple.
    Just find an object, that is going to be
  • 15:47 - 15:50
    triggered to some kind of synchronisation
    mechanism. In this case, it’s gonna be
  • 15:50 - 15:55
    just ‘Return to Menu’. And we
    create some kind of vague vtable
  • 15:55 - 16:00
    and get it to run our own
    stack pivot. And then we get…
  • 16:00 - 16:03
    we get ROP execution under
    Home menu, which is cool.
  • 16:03 - 16:07
    We still don’t have code execution
    in the Home menu, but that’s okay.
  • 16:07 - 16:11
    So, we can do a bunch of stuff from ROP.
  • 16:11 - 16:16
    We can access a new system
    service, which is called ‘ns:s’,
  • 16:16 - 16:20
    which is very helpful, because it can
    kill any arbitrary process, as well as
  • 16:20 - 16:25
    create new ones. Also it gives us access
    to SD card, which most applications
  • 16:25 - 16:30
    actually don’t have. And it lets us
    decrypt/dump any title on the system.
  • 16:30 - 16:34
    So any game, even if it uses new
    cryptography that Nintendo introduced,
  • 16:34 - 16:38
    we can actually dump that, because
    for some reason, well, Home menu
  • 16:38 - 16:42
    apparently needs access to
    that. And then we can also
  • 16:42 - 16:47
    access and overwrite all that extra data
    used by any application, which is great.
  • 16:47 - 16:50
    So we use this as a base
    for running homebrew.
  • 16:50 - 16:55
    Our homebrew launcher is
    essentially just a service
  • 16:55 - 16:59
    that runs in the background under Home
    menu process. It is written in ROP,
  • 16:59 - 17:02
    which is kind of disgusting, but it works.
    laughter
  • 17:02 - 17:06
    The ‘Service’ handles running homebrew,
    so the process is very simple. You just
  • 17:06 - 17:09
    kill off the current application, you
    spawn a new one, and then you take it over
  • 17:09 - 17:15
    using the GPU DMA access.
    And then, what we do is
  • 17:15 - 17:19
    we send all of these new capabilities that
    we got through handles to the new process
  • 17:19 - 17:24
    and that gives us some
    higher privilege homebrew.
  • 17:24 - 17:30
    It also handles events, such as Home
    button, Power button, all that good stuff.
  • 17:30 - 17:34
    Which is nice, because we can actually
    run code under any arbitrary application
  • 17:34 - 17:38
    or game, so we can actually modify
    these games. We can run ROM hacks.
  • 17:38 - 17:41
    So there has been a bunch of translations
    that can be run through this, for games
  • 17:41 - 17:44
    that haven’t come out outside
    of Japan, so that’s pretty nice.
  • 17:44 - 17:47
    It’s the same principle, you just
    launch the app, you take it over,
  • 17:47 - 17:51
    you pass the code, and then
    you jump to it, essentially.
  • 17:51 - 17:54
    All within the confines of
    userland, which is nice.
  • 17:54 - 18:00
    So, the other thing is, we can actually
    access any game or application’s data
  • 18:00 - 18:03
    because we can run code under
    it. So, these things include
  • 18:03 - 18:08
    savegame data for any game. So we
    can actually install more convenient
  • 18:08 - 18:12
    secondary entry points, which do not
    rely on the browser, which can be
  • 18:12 - 18:16
    patched any moment, or on some old game.
  • 18:16 - 18:21
    So, some examples include ‘Menuhax’
    by yellows8, which exploits
  • 18:21 - 18:28
    faulty theme handling code, which
    was introduced in firmware 9.0.
  • 18:28 - 18:31
    Which is really nice, because this way,
    you can actually just run homebrew
  • 18:31 - 18:35
    right as Home menu is opened,
    so right on boot time,
  • 18:35 - 18:39
    which is great. Then you got other games.
    Of course you got a Zelda game
  • 18:39 - 18:42
    that’s vulnerable.
    audience chuckles
  • 18:42 - 18:45
    This time it wasn’t the
    horse’s name, but pretty similar.
  • 18:45 - 18:48
    And then you got other games. We
    got tons of entry points at this point.
  • 18:48 - 18:55
    We’re really, literally drowning
    in them. So, this is nice.
  • 18:55 - 18:59
    But we forgot about ‘Nintendo Shell’,
    right? It’s a very attractive target,
  • 18:59 - 19:03
    for a couple of reasons. For one thing,
    it has access the ‘am:u’ service,
  • 19:03 - 19:06
    which can be used to
    downgrade any system title.
  • 19:06 - 19:10
    It’s not actually designed to downgrade
    titles, the thing is, you can both
  • 19:10 - 19:13
    install and uninstall titles.
    So, what happens is,
  • 19:13 - 19:17
    if you uninstall a title, and
    then install an older version
  • 19:17 - 19:19
    of that title, you actually
    bypass the version check.
  • 19:19 - 19:22
    So, you can just do that to
    downgrade any system title
  • 19:22 - 19:28
    and bring back old exploits,
    if that is necessary.
  • 19:28 - 19:30
    Assuming you have
    access to the service.
  • 19:30 - 19:33
    And of course it’s in a region
    that we can partially modify,
  • 19:33 - 19:36
    so it’s an interesting target.
  • 19:36 - 19:39
    Unfortunately, we can’t actually
    access its data right now.
  • 19:39 - 19:42
    But maybe we can actually move
    it to somewhere, where we can.
  • 19:42 - 19:48
    The idea is, if you were to kill NS, and
    then allocate something in it’s place,
  • 19:48 - 19:52
    then run NS again, you can
    move it below the cutoff.
  • 19:52 - 19:55
    laughter
  • 19:55 - 20:02
    applause
  • 20:02 - 20:06
    Thanks. But unfortunately
    it’s not that simple. That can’t work.
  • 20:06 - 20:11
    The reason being, that we actually need
    NS to be running to launch NS again.
  • 20:11 - 20:13
    So that kind of sucks.
  • 20:13 - 20:16
    But… well, no.
    Actually we also can’t run
  • 20:16 - 20:18
    a second instance of NS at the same time,
  • 20:18 - 20:20
    so we can’t do that either.
  • 20:20 - 20:24
    But interestingly…
    Well, the 3DS has an interesting feature,
  • 20:24 - 20:28
    which is called ‘Safe Mode’. Basically
    it’s a second firmware, which is
  • 20:28 - 20:33
    an old version of the
    regular one, and that
  • 20:33 - 20:37
    creates a bunch of
    copies of system titles.
  • 20:37 - 20:41
    Most of them, anyways. So that gives
    it a different ID. So, the idea is,
  • 20:41 - 20:44
    that if it has got a different ID, we
    might be able to run it at the same time,
  • 20:44 - 20:48
    because, well, PM might fail
    to notice that. Of course it doesn’t.
  • 20:48 - 20:52
    It actually does notice that. So we can’t
    run the Safe Mode version of a title
  • 20:52 - 20:55
    at the sime time as the regular
    version of the title. But,
  • 20:55 - 21:00
    for some reason, in the case of NS – you
    might not be able to see this very well,
  • 21:00 - 21:05
    but we’ve got NS’s regular title right
    here, and then we got Safe Mode NS
  • 21:05 - 21:07
    right here. And for some reason
    they created a new 3DS version
  • 21:07 - 21:12
    of the Safe Mode version of NS,
    though there is no new 3DS version
  • 21:12 - 21:16
    of the original NS. So that
    creates a separate title ID
  • 21:16 - 21:20
    which we can run at the same time
    as regular NS. So then, the exploit
  • 21:20 - 21:25
    becomes very simple. You keep NS running,
    just allocate enough data, that it will be
  • 21:25 - 21:29
    below the cutoff; and then you
    just run new 3DS Safe Mode NS.
  • 21:29 - 21:33
    And then it’s within range of the GPU
    and you can take it over and have
  • 21:33 - 21:37
    access to everything. So, this is nice.
  • 21:37 - 21:44
    It’s more of an oversight than
    a proper exploit, but whatever.
  • 21:44 - 21:46
    So this gives us access to a
    bunch of system calls. Mostly
  • 21:46 - 21:51
    service handling system calls,
    so we can post our own service,
  • 21:51 - 21:55
    which can be useful for other
    exploits that I won’t get into, for
  • 21:55 - 21:59
    impersonating other services
    to other system modules.
  • 21:59 - 22:03
    And then we got access to all of
    these services, which is great.
  • 22:03 - 22:07
    So we can downgrade
    system titles arbitrarily.
  • 22:07 - 22:11
    And this runs in background, which
    can always be helpful for homebrew.
  • 22:11 - 22:14
    The only problem is at this point,
    it’s still new 3DS only, because
  • 22:14 - 22:21
    it relies on this new 3DS title. But
    there are actually ways around that.
  • 22:21 - 22:24
    This was just to show that we can actually
    get fairly high levels of privilege,
  • 22:24 - 22:29
    even still just always staying
    in userland on the ARM11.
  • 22:29 - 22:32
    And there are other, similar attacks to
    that. If you’re interested you can look up
  • 22:32 - 22:36
    ‘rohax’, which is a similar
    attack in the system module.
  • 22:36 - 22:41
    So, now derrek is going to talk to you
    about exploiting the ARM11 kernel.
  • 22:41 - 22:52
    derrek?
    applause
  • 22:52 - 22:55
    derrek: So, hi everyone!
  • 22:55 - 23:00
    First, I will give you some
    very short inside view
  • 23:00 - 23:05
    of the kernel, and then I will
    explain how you can exploit
  • 23:05 - 23:09
    the latest version of the ARM11 kernel.
  • 23:09 - 23:12
    So,
  • 23:12 - 23:16
    this is actually Nintendo’s very
    first gaming console kernel.
  • 23:16 - 23:21
    Like on any other older console,
  • 23:21 - 23:26
    there was no kernel. All games
    were just running on bare metal.
  • 23:26 - 23:31
    Like there was a kernel for the Wii,
  • 23:31 - 23:36
    like a very small microkernel
    running on the security processor,
  • 23:36 - 23:41
    but that wasn’t written by Nintendo.
  • 23:41 - 23:45
    So it’s their very first
    gaming console kernel.
  • 23:45 - 23:51
    That kernel is made to be thread safe,
  • 23:51 - 23:55
    so it can run on multiple cores
  • 23:55 - 23:59
    at the same time and there are like
  • 23:59 - 24:03
    130 system calls available.
  • 24:03 - 24:07
    So that’s quite a lot, in my opinion.
  • 24:07 - 24:12
    But usually, if you have gained execution
  • 24:12 - 24:17
    in ARM11 userland, you
    only have access to, like,
  • 24:17 - 24:22
    around 50 system calls.
  • 24:22 - 24:27
    And there’s a reason for that, but I’m
    going to explain that in a second.
  • 24:27 - 24:34
    So, internally, the kernel
    works with C++ objects.
  • 24:34 - 24:38
    So here are some examples
    for system calls. So, we have
  • 24:38 - 24:44
    ‘CreateSemaphore’, for
    example. That will just create
  • 24:44 - 24:47
    a semaphore object in the kernel
  • 24:47 - 24:52
    and it will return a
    handle to the userland.
  • 24:52 - 24:56
    And when you want to do any operations
  • 24:56 - 25:00
    on that semaphore, you
    have to pass that handle
  • 25:00 - 25:05
    to the kernel, and it will look up
    this handle in a handle table
  • 25:05 - 25:11
    to find the original C++ object.
  • 25:11 - 25:16
    Also there are 2 different
    kinds of memory allocators.
  • 25:16 - 25:19
    So, we have a memory allocator
    for the main memory, which is
  • 25:19 - 25:25
    the FCRAM. And there is also a Slab Heap,
  • 25:25 - 25:30
    where all the C++ objects are stored in.
  • 25:30 - 25:35
    And this Slab Heap is located in FCRAM,
  • 25:35 - 25:39
    which is the ARM11 memory,
  • 25:39 - 25:44
    where all the kernel code and data is in.
  • 25:44 - 25:50
    Also, there’s an IPC system.
  • 25:50 - 25:54
    IPC is ‘inter process communication’.
  • 25:54 - 26:05
    And it basically allows you
    to talk to other processes
  • 26:05 - 26:08
    like services,
  • 26:08 - 26:17
    e.g. the GSP service or FS.
  • 26:17 - 26:22
    So, let’s look at the security.
  • 26:22 - 26:29
    So, the kernel is really small.
    There are only like 200KB of code,
  • 26:29 - 26:35
    which is pure ARM code. And
    there are only like 1000 functions.
  • 26:35 - 26:40
    So, they try to keep
    the code size very low
  • 26:40 - 26:47
    and that makes it harder to find bugs.
  • 26:47 - 26:52
    The code size is really small, and
  • 26:52 - 26:57
    you don’t have really much to choose from
  • 26:57 - 27:04
    what to exploit. Also there are no
    symbols included in the kernel.
  • 27:04 - 27:12
    Like when you run strings on it, it will
    just give you some names of C++ objects,
  • 27:12 - 27:16
    but there are no function
    names or something like that.
  • 27:16 - 27:21
    As we have seen earlier
    it’s physically isolated
  • 27:21 - 27:27
    in its own memory. Which turned out
    - of course - to be a good idea.
  • 27:27 - 27:34
    Otherwise it would have been
    overwritable by the CPU eventually.
  • 27:34 - 27:38
    And all objects have a reference counting.
  • 27:38 - 27:43
    So that’s similar to the
    C++ shared pointer
  • 27:43 - 27:50
    where every object has a small field
  • 27:50 - 27:54
    like a counter field and everytime
    the kernel wants to use an object
  • 27:54 - 28:00
    this counter gets increased.
    And everytime the…
  • 28:00 - 28:04
    like when the reference is no longer
    needed it will decrease the counter
  • 28:04 - 28:11
    and when the counter reaches Zero it
    will automatically delete that object
  • 28:11 - 28:19
    from the Slab Heap. So they are basically
    trying to prevent use after freeze.
  • 28:19 - 28:24
    Also I’m not sure if that’s
    a security measurement
  • 28:24 - 28:30
    but there are more than 100
    panic calls in the kernel
  • 28:30 - 28:36
    and that’s every 10th function
  • 28:36 - 28:44
    - per average. And they have
    the syscall access restriction.
  • 28:44 - 28:52
    So you - as I said - you only have
    access to like 50 system calls.
  • 28:52 - 28:55
    All the interesting ones are disabled.
  • 28:55 - 29:02
    E.g. you can’t map executable pages.
  • 29:02 - 29:06
    On the other hand there
    is no ASLR. But at least
  • 29:06 - 29:12
    they’re trying to change the
    memory mapping every time
  • 29:12 - 29:17
    during a larger kernel update.
  • 29:17 - 29:23
    Also there’s no stack protection. And
    the Userland is always mapped.
  • 29:23 - 29:29
    So once you’ve got control
    over the program counter
  • 29:29 - 29:33
    you can just jump to
  • 29:33 - 29:37
    Userland pages that are
    marked as executable.
  • 29:37 - 29:41
    So you don’t have to do ROP in the kernel.
  • 29:41 - 29:45
    It’s pretty nice.
  • 29:45 - 29:51
    But they tried to have
    an execution prevention
  • 29:51 - 29:58
    in the kernel that is: they’re
    marking executable kernel pages
  • 29:58 - 30:02
    – that is the code – they’re
    marking them as executable
  • 30:02 - 30:09
    in their Page Table. So let’s take a look.
  • 30:09 - 30:15
    The highlighted parts in orange
    are the kernel code sections.
  • 30:15 - 30:21
    And as you can see like when
    looking at the first highlighted line
  • 30:21 - 30:25
    it says ‘virtual address #FFF00’ etc.
  • 30:25 - 30:32
    is mapped to the physical
    address 1FF80000.
  • 30:32 - 30:40
    And it is marked as executable
    and you only have access to it
  • 30:40 - 30:45
    in Kernel Mode, of course,
    and only Read access. Right?
  • 30:45 - 30:50
    So this is correct.
  • 30:50 - 30:56
    But when you look at the second
    line of that Page Table dump
  • 30:56 - 31:01
    you will notice that
    there is another section
  • 31:01 - 31:06
    which covers the entire AXI WRAM
  • 31:06 - 31:10
    and it’s mapped as Read-Write.
  • 31:10 - 31:16
    So it doesn’t really make sense. Yeah.
  • 31:16 - 31:24
    So basically it’s completely useless.
    We have Read-Write access to it.
  • 31:24 - 31:28
    So, to summarize everything,
  • 31:28 - 31:33
    there’s actually no exploitation
    protection. Once we found
  • 31:33 - 31:39
    an exploitable bug it’s
    pretty likely that we gain
  • 31:39 - 31:43
    code execution in kernel mode.
  • 31:43 - 31:48
    So, let’s find that bug.
  • 31:48 - 31:54
    And I started at looking at the SVC table.
  • 31:54 - 32:00
    So this is kind of the interface
    between kernel land and userland.
  • 32:00 - 32:06
    And this shows all system calls
  • 32:06 - 32:11
    that are available in the kernel. So
    you have like normal system calls.
  • 32:11 - 32:18
    For memory management you can
    map read- and writable pages;
  • 32:18 - 32:25
    you can mirror pages and do
    other memory management stuff.
  • 32:25 - 32:31
    And there’s also some
    configuration for threads like
  • 32:31 - 32:38
    you can choose which
    core should be used for
  • 32:38 - 32:41
    executing the thread and all that stuff.
  • 32:41 - 32:47
    You have a really large range
    of synchronization objects
  • 32:47 - 32:51
    like kernel mute tags and
    all that stuff. And of course
  • 32:51 - 32:56
    you have IPC requesting, so you can
  • 32:56 - 33:03
    send messages to services. And
    there’s a more advanced section
  • 33:03 - 33:09
    like this is used by services mostly,
  • 33:09 - 33:15
    because they have to
    respond to your IPC requests.
  • 33:15 - 33:21
    And there’s also Kernel DMA,
    cache control, some things.
  • 33:21 - 33:27
    And they have a set of debug system calls.
  • 33:27 - 33:31
    It’s just basic debugging.
    You can set breakpoints,
  • 33:31 - 33:36
    read and write process memory.
    But you don’t have access to them.
  • 33:36 - 33:40
    Like on retail it’s not actually used.
  • 33:40 - 33:47
    And so one last section
    is the Privileged section.
  • 33:47 - 33:54
    And here are all the
    interesting system calls
  • 33:54 - 34:00
    that allow you to create processes and
  • 34:00 - 34:07
    map executable memory and all that stuff.
  • 34:07 - 34:14
    Unfortunately, we can’t use the Advanced,
    Debug and Privileged system calls.
  • 34:14 - 34:20
    I mean that would require
    exploiting some service.
  • 34:20 - 34:24
    And that’s just more work for us.
  • 34:24 - 34:29
    So this leaves us with
    the normal system calls.
  • 34:29 - 34:34
    But IPC sounds really interesting.
  • 34:34 - 34:41
    But unfortunately it’s full of panics.
  • 34:41 - 34:50
    Also there’s not much to attack at
    synchronization object system calls.
  • 34:50 - 34:59
    So you only have like this
    more interesting system call
  • 34:59 - 35:07
    for local memory management. And in
    theory there’s a lot that you can mess up.
  • 35:07 - 35:12
    Right? There’s a lot that can possibly
    go wrong. And also we have
  • 35:12 - 35:17
    unchecked DMA access!
    Like through the GPU.
  • 35:17 - 35:22
    So maybe we can do
    something useful with that.
  • 35:22 - 35:26
    Okay, so let’s have a look
    at the memory allocator.
  • 35:26 - 35:30
    There are 2 types of memory allocators.
  • 35:30 - 35:37
    First is the regular one. And it’s
    just for mapping normal heap
  • 35:37 - 35:44
    like for malloc in C, e.g. And you
    have the linear memory allocator
  • 35:44 - 35:49
    that is used for GPU textures, like
  • 35:49 - 35:55
    when memory has to be
    physically continuous
  • 35:55 - 35:59
    you use the linear memory allocator.
  • 35:59 - 36:04
    And there’s the FCRAM memory
    layout that we saw earlier.
  • 36:04 - 36:10
    You have these 3 regions
    and every region has
  • 36:10 - 36:15
    its own set of free pages.
  • 36:15 - 36:22
    So how are they keeping track of them?
  • 36:22 - 36:27
    So you have a region descriptor
    which tells us the dimensions like:
  • 36:27 - 36:32
    where does it start, the region,
    and its size. And you get also
  • 36:32 - 36:39
    a pointer to the first
    free piece of memory
  • 36:39 - 36:47
    in that region. And each
    free piece of memory
  • 36:47 - 36:54
    which we call a Memchunk
    has a Memchunk header
  • 36:54 - 36:58
    right at the beginning. And
    it basically tells the kernel
  • 36:58 - 37:04
    how large that Memchunk
    is. And it’s also linked
  • 37:04 - 37:08
    in a Doubly Linked List. So you
    have a next and previous pointer
  • 37:08 - 37:15
    pointing to the next and
    previous Memchunk headers.
  • 37:15 - 37:21
    It kind of looks like that.
    So you have the red parts
  • 37:21 - 37:29
    which are the free Memchunks
    and the green parts are memory
  • 37:29 - 37:35
    that is already allocated. So
  • 37:35 - 37:40
    allocation is pretty straightforward.
    It’s not really complicated.
  • 37:40 - 37:46
    So the first thing that the
    allocator function does:
  • 37:46 - 37:52
    it loads the next free pointer
    from the region descriptor.
  • 37:52 - 37:59
    And for regular memory it
    just goes through the list
  • 37:59 - 38:05
    following the pointers
    and it sums up their size
  • 38:05 - 38:11
    until the requested size is reached.
    For linear memory it would just
  • 38:11 - 38:17
    look for a suitable memory chunk to make
    sure that the memory is really continuous.
  • 38:17 - 38:22
    So when it found enough memory
    it sets the next pointer
  • 38:22 - 38:28
    of the very last Memchunk
    to Zero. It will then
  • 38:28 - 38:34
    update the list and also
    the next free pointer
  • 38:34 - 38:39
    for the region descriptor
    and finally it will return
  • 38:39 - 38:45
    a pointer to the first
    Memchunk. So,
  • 38:45 - 38:49
    let’s look at this from
    a security perspective.
  • 38:49 - 38:53
    And there’s a problem. They
    basically have kernel structures
  • 38:53 - 39:00
    inside the FCRAM!
    And that is a problem
  • 39:00 - 39:04
    because we have DMA access
    to it through the GPU.
  • 39:04 - 39:09
    And there was an attack by yellows8
  • 39:09 - 39:13
    that is called ‘memchunkhax’.
    And what he did
  • 39:13 - 39:17
    is basically: he overwrote
    memchunk headers
  • 39:17 - 39:22
    with the GPU DMA
    flaw. And then
  • 39:22 - 39:27
    he gained an arbitrary kernel write
  • 39:27 - 39:32
    when it’s deallocating memory. So because
  • 39:32 - 39:37
    next/prev pointers have been modified.
  • 39:37 - 39:42
    So, unfortunately, this
    was fixed by Nintendo
  • 39:42 - 39:48
    in system update 9.3 last year,
  • 39:48 - 39:54
    like 1 year ago. And the new kernel will
    now verify every memchunk header
  • 39:54 - 40:00
    during allocation. Like its size
    and also next/prev pointers.
  • 40:00 - 40:08
    So, in theory, everything has been fixed.
    Invalid pointers or invalid sizes
  • 40:08 - 40:17
    will just result in a
    kernel panic. In theory.
  • 40:17 - 40:22
    So when you look at the system
    call for Controlmemory…
  • 40:22 - 40:29
    we have access to it. It’s one
    of the normal system calls.
  • 40:29 - 40:34
    It does basic stuff. You
    can map/free RW pages,
  • 40:34 - 40:41
    but not executable of course. And it
    takes an address and size as argument.
  • 40:41 - 40:47
    And also an operation code
    which tells the kernel what to do:
  • 40:47 - 40:51
    to map or free pages, whatever.
  • 40:51 - 40:56
    So first it does some basic
    checks on the address
  • 40:56 - 41:02
    and eventually it will
    call a very large function.
  • 41:02 - 41:09
    And I just call that function
    kern::controlmemory.
  • 41:09 - 41:15
    So what can kern::controlmemory:
    it calls the allocator function
  • 41:15 - 41:21
    and it will just return a
    memchunk header pointer
  • 41:21 - 41:28
    – as we have seen earlier. Then it goes
    through all of the allocated memchunks
  • 41:28 - 41:33
    and it’s mapping them to user space.
  • 41:33 - 41:40
    And it’s also updating some block
    information for KProcess object.
  • 41:40 - 41:47
    So there’s a problem. There’s
    obviously a race condition.
  • 41:47 - 41:57
    Like we can overwrite memchunk
    headers after they have been allocated.
  • 41:57 - 42:04
    So we could try using the GPU
    but it’s really slow, actually,
  • 42:04 - 42:11
    because we would have to ask
    the GSP service to read memory
  • 42:11 - 42:20
    and we have to go to this
    very large IPC kernel code.
  • 42:20 - 42:27
    And that would be probably too
    slow. Allocation is really fast.
  • 42:27 - 42:31
    Let’s dig a little bit deeper.
  • 42:31 - 42:38
    I tried to reconstruct
    the source code in C.
  • 42:38 - 42:44
    So this is the first step.
    It tries to allocate memory.
  • 42:44 - 42:54
    For this example, it will just
    allocate regular memory.
  • 42:54 - 42:59
    So when it found a memchunk
  • 42:59 - 43:05
    which means that it’s not
    enough memory is available.
  • 43:05 - 43:12
    It will then execute this
    really interesting do-while loop.
  • 43:12 - 43:16
    I know, it’s a lot of code. I’m not
    sure that you can actually read it.
  • 43:16 - 43:22
    So let’s go quickly through this code.
  • 43:22 - 43:28
    The pages read from the Memchunk header.
    It gets converted to a physical address.
  • 43:28 - 43:32
    And that physical address
    gets mapped to userland
  • 43:32 - 43:39
    by mem_map function. And then
    it will go to the next memchunk.
  • 43:39 - 43:45
    Here. And it will also update
    the userland virtual address.
  • 43:45 - 43:50
    And then it will clear that memory. So
  • 43:50 - 43:54
    what’s wrong here?
  • 43:54 - 44:00
    The problem is they’re mapping
    the Memorychunk into userland.
  • 44:00 - 44:06
    And after it has been mapped
    they’re accessing it again.
  • 44:06 - 44:10
    And what they access is the next pointer.
  • 44:10 - 44:13
    So we can just overwrite it.
  • 44:13 - 44:20
    When we have 2 threads running we can
  • 44:20 - 44:25
    – from another CPU core –
    try to overwrite that pointer.
  • 44:25 - 44:32
    So our goal would be to map
    kernel pages to userspace.
  • 44:32 - 44:38
    But there are some problems. It
    requires really, really perfect timing.
  • 44:38 - 44:45
    There’s only a very small
    time frame to do the overwrite.
  • 44:45 - 44:54
    Also, we need a Memchunk header
    structure at the next pointer address…
  • 44:54 - 45:01
    …to do this. To make sure
    we get a perfect timing
  • 45:01 - 45:07
    I came up with a kernel
    address arbiter oracle.
  • 45:07 - 45:12
    It is actually used for thread
    synchronization, we don’t care about it.
  • 45:12 - 45:15
    But it tries to read from address and
    returns an error when the address is
  • 45:15 - 45:24
    not accessible by userland. So
    we can use that system call
  • 45:24 - 45:29
    to make sure that the memory
    has been mapped to userland.
  • 45:29 - 45:32
    And once it has been mapped
    we’re trying to overwrite it.
  • 45:32 - 45:38
    So one last problem: we have to
    inject a memory chunk error
  • 45:38 - 45:45
    in kernel. I did this
    by using the Slab Heap.
  • 45:45 - 45:51
    We can just create some KObject
    and set their member variables
  • 45:51 - 45:56
    to create a faked memchunk header.
  • 45:56 - 46:00
    So this is the Slab Heap.
    We’ve got C++ objects,
  • 46:00 - 46:05
    vtable pointer and some attributes.
  • 46:05 - 46:11
    So the Slab Heap is basically just
    a really large area of C++ objects.
  • 46:11 - 46:17
    And what I did was
    I changed the attributes
  • 46:17 - 46:22
    and used them as Memchunk
    header. And I am redirecting
  • 46:22 - 46:30
    the next-pointer to that
    object and it will map
  • 46:30 - 46:34
    multiple C++ objects to userland.
    And that’s really nice because
  • 46:34 - 46:40
    we have vtable pointers, so
    we can just overwrite them.
  • 46:40 - 46:44
    And that means that
    we gain code execution.
  • 46:44 - 46:50
    So, as a summary, we set
    up some kernel objects,
  • 46:50 - 46:53
    change their attributes, request
    memory from the kernel;
  • 46:53 - 46:57
    and once it becomes available
    we patch the next-pointer,
  • 46:57 - 47:02
    overwrite that mapped
    SlabHeap pages and
  • 47:02 - 47:08
    then we call a system call
    which closes the handle
  • 47:08 - 47:12
    for the kernel objects that
    we created in step one.
  • 47:12 - 47:17
    So it will eventually call
    some vtable function
  • 47:17 - 47:24
    and it will just jump to our
    modified vtable function.
  • 47:24 - 47:29
    And we got ARM11
    Level0 Code Execution!!
  • 47:29 - 47:39
    applause, motivated by smea
  • 47:39 - 47:44
    So, now plutoo will tell us
    what nice things you can do
  • 47:44 - 47:47
    once you gained ARM11
    Code execution.
  • 47:47 - 47:55
    plutoo: Hey guys! Okay, so… the ARM9.
  • 47:55 - 47:59
    Let’s go.
  • 47:59 - 48:06
    The ARM9 is actually also used
    for executing old DS games.
  • 48:06 - 48:10
    So what they do is, they actually,
    you could say, reused the ARM9
  • 48:10 - 48:14
    which is their backwards compatibility
    processor. They use it
  • 48:14 - 48:21
    as a security processor
    when executing 3DS code.
  • 48:21 - 48:25
    And like smea said it’s running
    a stripped-down version
  • 48:25 - 48:31
    of the ARM11 kernel. It basically
    only does threading sequencation,
  • 48:31 - 48:35
    things like that. And there’s
    no MMU. There’s an MPU,
  • 48:35 - 48:40
    8 regions you can configure.
  • 48:40 - 48:46
    You could do no-execute
    within those regions etc. but
  • 48:46 - 48:50
    the granularity is not very
    nice. And they only have 8.
  • 48:50 - 48:55
    So they basically ran out of space.
    And .data+stack is executable
  • 48:55 - 49:00
    as long as you can jump to
    it. And .text is writable
  • 49:00 - 49:06
    so that’s bad. Basically whenever you can
  • 49:06 - 49:12
    write code into arbitrary memory
    you can just overwrite code.
  • 49:12 - 49:16
    These features – you don’t want
    them on a security processor.
  • 49:16 - 49:18
    laughter
  • 49:18 - 49:24
    So let’s go. So it turns out that
  • 49:24 - 49:28
    there have been lots of exploits over
    the years and most of them are fixed.
  • 49:28 - 49:33
    And most of them used the
    normal command interface.
  • 49:33 - 49:38
    But in this case we’re taking
    a different approach. So
  • 49:38 - 49:43
    on the 3DS the memory-mapped
    I/O is split up into 3 regions.
  • 49:43 - 49:46
    There’s the ARM9-only I/O: it does crypto,
  • 49:46 - 49:51
    it does DMA engine,
  • 49:51 - 49:55
    things like that. Then there’s
    the Shared I/O region.
  • 49:55 - 49:58
    And then, finally, there’s the
    ARM11 I/O region which contains
  • 49:58 - 50:03
    the GPU video decoder.
  • 50:03 - 50:06
    Thanks to derrek and smea
    we have full ARM11 control.
  • 50:06 - 50:10
    We execute kernel mode.
  • 50:10 - 50:13
    So the question is: can we use
    the shared I/O region, somehow,
  • 50:13 - 50:18
    to own the ARM9? So it turns out
  • 50:18 - 50:22
    the interface for reading old
    DS cartridges is actually
  • 50:22 - 50:25
    in the shared I/O region.
  • 50:25 - 50:30
    We’re not sure why this is, but
  • 50:30 - 50:34
    they have it there for some
    reason. And it’s only the ARM9
  • 50:34 - 50:38
    which is actually using this region.
    But ARM11 still has access to it.
  • 50:38 - 50:44
    So when you insert the cartridge
    it starts by reading the banner.
  • 50:44 - 50:49
    And it does this by writing this
    magic value to CTRL register.
  • 50:49 - 50:54
    And basically it just asks
    for 0x200 [hex] bytes.
  • 50:54 - 50:56
    And then there’s this loop.
  • 50:56 - 51:00
    And this Assembler code
    is on the right side.
  • 51:00 - 51:05
    You can see it basically waits
    for some bits to clear / to set
  • 51:05 - 51:11
    and then they read 4 bytes and
    then they wait for another bit.
  • 51:11 - 51:16
    And there’s no range check on the
    buffer. But it’s always 200 bytes,
  • 51:16 - 51:21
    so it should be fine.
  • 51:21 - 51:25
    What if we overwrite the
    CTRL register from ARM11
  • 51:25 - 51:28
    asking for 0x4000 bytes?
  • 51:28 - 51:32
    Boom!
  • 51:32 - 51:36
    We have a nice buffer overrun.
    It’s in the DSS segment but…
  • 51:36 - 51:41
    it’s still nice. And can control the data.
  • 51:41 - 51:48
    So the data actually comes
    from the cartridge.
  • 51:48 - 51:52
    We need to make our
    own DS cartridge. So,
  • 51:52 - 51:56
    there’s this old device, called the
    PassMe. It’s for the original DS,
  • 51:56 - 52:00
    where you basically plug
    old DS cartridge in
  • 52:00 - 52:04
    and it basically modifies
    the header as its read. So,
  • 52:04 - 52:09
    these are available online for 5 bucks.
  • 52:09 - 52:15
    And then you add an FPGA.
  • 52:15 - 52:21
    I implemented this and it
    works, but it’s very gimmicky.
  • 52:21 - 52:26
    I don’t recommend it.
  • 52:26 - 52:31
    And here’s my soldering,
    it’s not very nice.
  • 52:31 - 52:36
    This gives us ARM9 code execution
    and this works on latest firmware.
  • 52:36 - 52:41
    But we want something better.
    Let’s look at the chain of trust.
  • 52:41 - 52:47
    The chain of trust: the idea is of course,
    you verify all the code that is running.
  • 52:47 - 52:52
    But you’re basically verifying
    everything at load time.
  • 52:52 - 52:55
    The 3DS has the simplest
    chain of trust you can have.
  • 52:55 - 52:59
    There’s the Boot ROM at
    the start. And then it loads
  • 52:59 - 53:04
    the firmware binary from
    NAND and it jumps to it.
  • 53:04 - 53:08
    On the new 3DS they were a bit clever.
  • 53:08 - 53:13
    They added an extra crypto
    layer on the ARM9 portion.
  • 53:13 - 53:18
    But it’s actually part
    of the firmware binary.
  • 53:18 - 53:20
    We call this ‘ARM9 loader’.
  • 53:20 - 53:24
    So the theory that Nintendo had was:
  • 53:24 - 53:27
    “Let’s add another layer of
    crypto, so we change the keys,
  • 53:27 - 53:32
    we introduce new keys,
    and they can’t break it”.
  • 53:32 - 53:36
    And they don’t have any worked-out
    place to put those keys.
  • 53:36 - 53:39
    So they placed them in NAND!
  • 53:39 - 53:43
    But they’re encrypted with
    the per-Console key that’s
  • 53:43 - 53:48
    based on a hash of the OTP
    that’s unique for each Console.
  • 53:48 - 53:52
    And then OTP access is
    disabled early in the Boot.
  • 53:52 - 53:59
    So later on you can’t dump the OTP
    and you can’t figure out the keys.
  • 53:59 - 54:04
    This looks safe, in theory.
    So here’s the implementation.
  • 54:04 - 54:09
    So they calculate some hash of the OTP.
    They read the key-sector from NAND.
  • 54:09 - 54:12
    And they decrypt the key.
    And they put it in a keyslot.
  • 54:12 - 54:17
    It’s basically an isolated memory area.
  • 54:17 - 54:21
    And then they generate
    a bunch of sub keys and
  • 54:21 - 54:25
    they verify that the key they loaded
    from NAND is the correct one.
  • 54:25 - 54:31
    So even if we were to switch the key
    they would detect that and just panic.
  • 54:31 - 54:35
    And then they decrypt the ARM9 binary
    and they jump to the entry point.
  • 54:35 - 54:40
    But… they forgot to clear the 0x11 key!
  • 54:40 - 54:44
    So we can just get code execution
    later on. And we can just regenerate
  • 54:44 - 54:51
    all those keys! So this
    implementation is useless.
  • 54:51 - 54:53
    Okay.
    laughs
  • 54:53 - 54:59
    applause
  • 54:59 - 55:04
    And they fixed this because they have
    more than 1 key hidden in the NAND.
  • 55:04 - 55:08
    So they took their next key.
  • 55:08 - 55:11
    It’s basically the same idea: you
    calculate the same hash, you read
  • 55:11 - 55:15
    the key sector from NAND, you generate
    all the previous keys for compatibility,
  • 55:15 - 55:20
    and then you decrypt a
    new key, we call it Key#2.
  • 55:20 - 55:24
    And then you decrypt ARM9
    binary using the second key.
  • 55:24 - 55:28
    You clear the keyslot, and
    you jump to entry point.
  • 55:28 - 55:32
    But they forgot to verify the second key!
    audience laughs
  • 55:32 - 55:40
    This is epic fail!
    applause
  • 55:40 - 55:45
    So let’s exploit this. ‘ARM9LOADERHAX’.
  • 55:45 - 55:50
    We can change the second key. ARM9
    loader will just decrypt the binary
  • 55:50 - 55:55
    to garbage and jump to it.
  • 55:55 - 56:00
    If you look at the encoding
    of a ARM Branch instruction:
  • 56:00 - 56:04
    the probability is pretty high that
    there will just be a Branch instruction.
  • 56:04 - 56:09
    And just any random data will eventually…
    like if you try enough keys,
  • 56:09 - 56:15
    it will eventually become a Branch
    instruction to some memory.
  • 56:15 - 56:19
    So if we try a lot of keys, eventually
    we will find some garbage
  • 56:19 - 56:24
    that is useful.
  • 56:24 - 56:30
    This is the NAND of the Flash
    memory of an unmodified 3DS
  • 56:30 - 56:37
    – a new 3DS. So there’s a small key
    section, marked in teal, like, blue.
  • 56:37 - 56:42
    And it contains those keys
    that we’re talking about.
  • 56:42 - 56:45
    And then there are 2 firmware partitions.
  • 56:45 - 56:48
    One is used for backup, in
    case one gets corrupted;
  • 56:48 - 56:52
    so it doesn’t brick the device, whatever.
  • 56:52 - 56:57
    We installed our custom key.
  • 56:57 - 57:01
    And we installed the largest
    firm binary we have
  • 57:01 - 57:06
    in the firm0 partition. And we keep
    the one with the vulnerability
  • 57:06 - 57:12
    in the firm1 partition. And
    then we put our code payload
  • 57:12 - 57:17
    on top of the firmware0 binary.
  • 57:17 - 57:21
    And then we reboot.
    And so what will happen?
  • 57:21 - 57:24
    The Bootrom is executed.
  • 57:24 - 57:30
    It will load the first firmware partition.
  • 57:30 - 57:35
    And it has our code in the end,
    but it doesn’t know about it.
  • 57:35 - 57:39
    And then it decrypts it.
    And, you see, it looks okay.
  • 57:39 - 57:44
    There’s the ARM9 loader stub in the front;
    and then comes the encrypted binary.
  • 57:44 - 57:48
    And then, finally,
    there’s our payload.
  • 57:48 - 57:53
    But Bootrom checks the
    hash, right? And it fails.
  • 57:53 - 57:58
    So it thinks the partition got corrupted.
  • 57:58 - 58:03
    So it will load the smaller one on top.
    You see we have our payload in memory,
  • 58:03 - 58:09
    at Boot. And then it decrypts firmware1
  • 58:09 - 58:15
    which is smaller and it still has ARM9
    loader and another encrypted ARM9 binary.
  • 58:15 - 58:19
    And then it jumps to ARM9 loader
    because the hash checks out.
  • 58:19 - 58:24
    And then the ARM9 loader will
    decrypt our corrupted key
  • 58:24 - 58:29
    from NAND and it will
    decrypt this one to garbage
  • 58:29 - 58:37
    and it will jump to it. And
    hopefully it jumps to our code.
  • 58:37 - 58:42
    So this gives us ARM9 code
    execution from cold Boot.
  • 58:42 - 58:46
    Early, very early. So it turns out we
    can actually use this to get some keys
  • 58:46 - 58:52
    that are later not available
    because they clear those…
  • 58:52 - 58:57
    they use a certain memory area for seeding
    encryption engine to generate keys
  • 58:57 - 59:04
    and the memory is later cleared.
    So you can’t regenerate the keys.
  • 59:04 - 59:08
    But with this we can actually
    get those 2 keys.
  • 59:08 - 59:12
    They’re called the firmware 6.x save-key
  • 59:12 - 59:16
    and firmware 7.x NCCH-key.
  • 59:16 - 59:20
    That’s a bonus.
  • 59:20 - 59:25
    We talked a bit about the AES engine.
    It’s used everywhere for the crypto
  • 59:25 - 59:30
    and it’s used for everything, basically.
  • 59:30 - 59:36
    It supports all the usual
    block cipher modes.
  • 59:36 - 59:41
    It has 2 security features: it has
    write-only keys. Which is really useful.
  • 59:41 - 59:45
    Like you write a key and then
    you can never ever read it back.
  • 59:45 - 59:50
    This means that they can
    fill in the keys by the Bootrom
  • 59:50 - 59:56
    and we can’t dump them later.
  • 59:56 - 60:01
    So they can keep the keys secret.
  • 60:01 - 60:08
    Even if we hacked the ARM9, even if we get
    code execution we’ll never get the keys.
  • 60:08 - 60:12
    And then there’s the key scrambler.
    Which is that the key is actually
  • 60:12 - 60:16
    – it’s an optional thing –
    where the actual key is hidden,
  • 60:16 - 60:21
    calculated by a hardware
    function, that is never…
  • 60:21 - 60:26
    that we don’t know about. So the key
    is actually never exposed to the CPU
  • 60:26 - 60:31
    – the actual key. So we just feed it 2
    values, 2 keys and then it generates
  • 60:31 - 60:35
    a new key based on that. And
    we don’t know what that key is.
  • 60:35 - 60:40
    So this creates a situation similar to
    the isolated SPUs on the PS3
  • 60:40 - 60:44
    where you can ask it to decrypt
    stuff, but you don’t get the keys.
  • 60:44 - 60:50
    And if you don’t get the keys,
    then… we want the keys!!
  • 60:50 - 60:53
    We want to decrypt things on
    our PC because we’re lazy.
  • 60:53 - 60:58
    So there’re 2 keys –
    KeyX, KeyY we call them.
  • 60:58 - 61:02
    They’re 128bits and the
    normal key is derived
  • 61:02 - 61:06
    as a function of those 2;
    and that function is unknown.
  • 61:06 - 61:12
    It’s implemented in hardware, in silicon.
  • 61:12 - 61:16
    So even if we know X and Y we
    can’t figure out the normal key
  • 61:16 - 61:22
    and we can’t decrypt things
    without asking the 3DS first.
  • 61:22 - 61:27
    But we can poke this hardware engine.
  • 61:27 - 61:30
    The first thing you notice when you
    do this is that if you set the N-th bit
  • 61:30 - 61:37
    of the X key and the N+2 bit in
    the Y key you get the same result.
  • 61:37 - 61:41
    And in general, you find that
    the function that we’re looking for
  • 61:41 - 61:45
    is actually just a function
    of one variable where it’s
  • 61:45 - 61:51
    the XOR between the X rotated by 2…
  • 61:51 - 61:56
    so this is rotation, not shift,
    and XOR-ed with Y.
  • 61:56 - 61:59
    But we still don’t know the key.
    But we want to know keys. So…
  • 61:59 - 62:08
    So step back a little bit.
  • 62:08 - 62:12
    The keyscrambler is used for Mii QR-codes.
  • 62:12 - 62:19
    It’s used for everything, right? So it’s
    used for network protocol, called UDS,
  • 62:19 - 62:24
    and it’s used for Download Play – which
    is when you download games over WiFi,
  • 62:24 - 62:28
    temporary games. But the
    Wii U also supports all of this.
  • 62:28 - 62:31
    But it doesn’t have the
    key scrambler in hardware.
  • 62:31 - 62:33
    So the Wii U must be using normal keys.
  • 62:33 - 62:37
    applause
    screamed from audience: WHAT?
  • 62:37 - 62:46
    applause
  • 62:46 - 62:51
    So we make a table of the shared keys and
  • 62:51 - 62:55
    these are the 3 keys that
    are shared with the Wii U.
  • 62:55 - 63:00
    Who is where the KeyX
    and KeyY on the 3DS…
  • 63:00 - 63:06
    where they are set. And 2 of them
    have KeyY set by firmware.
  • 63:06 - 63:12
    So we can’t read the keys set by the
    Bootrom because it’s locked away
  • 63:12 - 63:17
    and we don’t have it. But can
    we still figure out G? Let’s see.
  • 63:17 - 63:23
    So I gave shoutout to shuffle2 and
    to fail0verflow who hacked the WiiU
  • 63:23 - 63:28
    and they helped us… or shuffle
    helped us extract the Wii U keys.
  • 63:28 - 63:37
    So thank you! Now we have KeyY and
    we know the normal key from the Wii U.
  • 63:37 - 63:40
    However, KeyX is still unknown.
  • 63:40 - 63:45
    And if G(t) is ‘bad’ then a
    small change in the KeyY
  • 63:45 - 63:49
    will only lead to a small
    change in the normal key.
  • 63:49 - 63:53
    It’s bad! So let’s look at the data.
  • 63:53 - 63:57
    So when we flip one bit in the
    KeyY we can brute-force all keys
  • 63:57 - 64:01
    similar to the normal key which
    is just within a couple of bit flips
  • 64:01 - 64:07
    and we find that it always
    results in the normal key
  • 64:07 - 64:13
    with bits flipped at
    position either 87 or 88,
  • 64:13 - 64:16
    sometimes 89, but never 86.
  • 64:16 - 64:22
    So this reminds me of an adder
    where you had a carry bit
  • 64:22 - 64:26
    being propagated to upper
    bits, but never to lower ones.
  • 64:26 - 64:31
    So let’s guess that this is
    an adder and let’s try:
  • 64:31 - 64:38
    it’s an adder with a rotation so
    we guess that G(t) = (t+C)
  • 64:38 - 64:45
    – some constant C, we don’t know it –
    and rotated to the left by 87.
  • 64:45 - 64:51
    And then we plug it in to our original
    formula and we don’t know KeyX, remember,
  • 64:51 - 64:54
    because it’s set by Bootrom,
    we don’t have it.
  • 64:54 - 64:59
    We don’t know the constant C because
    it’s in silicon, it’s in hardware.
  • 64:59 - 65:05
    But if we look at the formula,
    and we consider the inequality,
  • 65:05 - 65:09
    where we basically rotate right by 87
  • 65:09 - 65:14
    – we’re basically undoing
    the outer rotation.
  • 65:14 - 65:19
    And then we plug in our formula
    our guess. And then we get this.
  • 65:19 - 65:23
    And then we subtract C from
    both sides. We end up with this.
  • 65:23 - 65:29
    And this is basically… we’re XOR-ing
    2 different keys with the same X value
  • 65:29 - 65:35
    rotated to the left by 2.
  • 65:35 - 65:38
    Well if you stare for
    this bit you’ll see that
  • 65:38 - 65:46
    if y0 and y1 – which are 2 different
    KeyY’s – are equal except for
  • 65:46 - 65:52
    at one bit position then
    the XOR is smallest
  • 65:52 - 65:58
    for the one which shares
    the same bit value
  • 65:58 - 66:03
    at the position that the
    2 Y’s are differing at.
  • 66:03 - 66:08
    It’s actually pretty simple
    but it sounds difficult.
  • 66:08 - 66:13
    XOR is Zero if they’re the same
    input and One if they’re different.
  • 66:13 - 66:16
    If they’re the same it’s
    Zero and it’s smaller.
  • 66:16 - 66:21
    So we actually look
    bit-by-bit on this. And
  • 66:21 - 66:28
    we repeat this 128 times. And we
    recover all 128 bits of the KeyX.
  • 66:28 - 66:33
    And when we have the KeyX we can
    calculate the silicon constant C.
  • 66:33 - 66:38
    So the end result is: the key
    scrambler is figured out
  • 66:38 - 66:45
    and we have also the secret Bootrom
    KeyX for a couple of keyslots, as a bonus.
  • 66:45 - 67:01
    applause, motivated by smea
  • 67:01 - 67:05
    I didn’t think trough the constants in
    the slides because I want this to be
  • 67:05 - 67:12
    an exercise for the listener.
  • 67:12 - 67:16
    When the new 3DS was released
    they rushed it, we think,
  • 67:16 - 67:22
    because they left some interesting
    commands in the PsPs service. And
  • 67:22 - 67:31
    it included an early version of the NFC
    crypto used for the Amiibo figurines.
  • 67:31 - 67:37
    This implementation, the first
    one, uses a normal key. And the…
  • 67:37 - 67:40
    the newer one changed it to KeyY.
  • 67:40 - 67:44
    So they accidently gave us one of
    these pairs in the firmware images.
  • 67:44 - 67:47
    We don’t need to use the Wii U at all.
  • 67:47 - 67:52
    So anyone who can decrypt
    3DS firmware binaries
  • 67:52 - 67:58
    can perform this attack
    to get the constants.
  • 67:58 - 68:03
    So anyone out there: Good luck!
  • 68:03 - 68:07
    And now: back to smea, for a summary.
  • 68:07 - 68:14
    applause
  • 68:14 - 68:17
    smea: Right, I’m just gonna conclude
    really quickly. So, some take-aways of
  • 68:17 - 68:21
    what we talked about
    today: first thing is:
  • 68:21 - 68:24
    it’s all pretty obvious lessons,
    but – you know – bare with me
  • 68:24 - 68:29
    Giving access to physical memory to
    any application, through GPU or whatever,
  • 68:29 - 68:32
    is dangerous. You should always be
    careful about that. Even if you think
  • 68:32 - 68:36
    you’ve protected stuff, there’s probably
    gonna be stuff that you forgot. So just,
  • 68:36 - 68:40
    like “you don’t do it or do it right”.
  • 68:40 - 68:42
    Other thing is: Shared I/O is
    dangerous if you don’t know
  • 68:42 - 68:48
    what can actually control the I/O, then,
    well, again, you should be very careful.
  • 68:48 - 68:52
    Also, only checking your data
    before decryption is dangerous,
  • 68:52 - 68:56
    and - both that and not checking the key
    when you know that it could possibly
  • 68:56 - 69:01
    be modified by an attacker
    is a bad idea. And finally,
  • 69:01 - 69:05
    secrets in hardware are great
    unless you give them away, so…
  • 69:05 - 69:08
    don’t do that! laughs
    audience laughs*
  • 69:08 - 69:11
    Beyond that we just wanted to talk about
    the state of Homebrew really quickly.
  • 69:11 - 69:15
    You might recall, on the - during the
    Wii U talk around here
  • 69:15 - 69:20
    2 years ago. And fail0verflow said
    that they didn’t think necessarily
  • 69:20 - 69:24
    there was much of a future for console
    Homebrew. And there’s definitely
  • 69:24 - 69:29
    an argument for that with
    the rise of phones, mostly.
  • 69:29 - 69:32
    Anyone can make an app, can make
    a game for any number of devices
  • 69:32 - 69:37
    and sell it to millions of people.
    But you know, we disagree.
  • 69:37 - 69:39
    cheers and applause
  • 69:39 - 69:44
    It’s been a year since we started
    releasing 3DS homebrew. And
  • 69:44 - 69:48
    – this is supposed to be moving,
    but… let’s imagine it’s moving.
  • 69:48 - 69:52
    Well, there in there - like a bunch of
    3DS Homebrew. It’s been awesome!
  • 69:52 - 69:56
    We’ve been working on this really hard.
    A lot of people had been joining us.
  • 69:56 - 70:02
    It’s a great community effort. And
    basically what I want to say is
  • 70:02 - 70:06
    we want more developers.
    So if you’d like to join us
  • 70:06 - 70:11
    there is a very… well it’s not
    very mature, but it’s maturing,
  • 70:11 - 70:15
    our SDK. And you know what:
    reverse-engineering hardware is fun.
  • 70:15 - 70:18
    When we don’t have any documentation,
    reverse-engineering software is fun.
  • 70:18 - 70:23
    We can always use more reverse-engineers
    and just people who want to make cool shit,
  • 70:23 - 70:29
    so… Yeah, oh… right! Just one more thing.
  • 70:29 - 70:33
    Lately there has been a wave
    of patches by Nintendo,
  • 70:33 - 70:36
    of known exploits, which
    has been really annoying.
  • 70:36 - 70:40
    So for our Browser Hacks, well,
    yellows8’s Browser Hacks,
  • 70:40 - 70:45
    menu hacks, stuff like that…
    Yellows8’s been working pretty hard,
  • 70:45 - 70:49
    so he actually brought back browser
    hacks, it should have been released
  • 70:49 - 71:03
    about 10 minutes ago.
    laughter, applause
  • 71:03 - 71:08
    But we also had ironhax for an
    eShop game, a free eShop game,
  • 71:08 - 71:12
    so you could just download it. That was
    patched. The thing is, there’s actually
  • 71:12 - 71:17
    a way to download the old version from
    the eShop application with some patches.
  • 71:17 - 71:20
    So we’re also releasing that right now!
    So basically if you can get Homebrew
  • 71:20 - 71:24
    and get on to the eShop
    with a modified patch.
  • 71:24 - 71:28
    That should also be released in about…
    well, whenever this is done.
  • 71:28 - 71:31
    So get it as soon as possible,
    this is a free game, it will get you
  • 71:31 - 71:37
    Homebrew forever. So just do that.
    And also, yellows8 just released
  • 71:37 - 71:40
    a new version of menuhax which
    works on latest firmware version.
  • 71:40 - 71:43
    This was also patched like a couple of
    weeks or months ago. So, this is all out
  • 71:43 - 71:48
    right now. If you have a 3DS, get it.
    If you have friends who have 3DS’s,
  • 71:48 - 71:54
    well, tell them and tell them to get it.
    Because it might not last super long.
  • 71:54 - 71:58
    Yeah, so we would like to thank yellows8
    who unfortunately can not be here tonight
  • 71:58 - 72:02
    but has been super helpful, has been
    doing a ton of work on the 3DS.
  • 72:02 - 72:05
    And honestly, a ton of this could
    not have been done without him.
  • 72:05 - 72:09
    And thanks to everyone on the
    #3DSDEV Homebrew channel,
  • 72:09 - 72:12
    everyone who is attending tonight.
    Thanks for this.
  • 72:12 - 72:15
    And if you have any questions,
    I don’t think we have a lot of time,
  • 72:15 - 72:28
    but we’ll accommodate. Thanks!
    applause
  • 72:28 - 72:32
    Herald: Thank you for your patience, if
    you got questions, please come upfront
  • 72:32 - 72:36
    to these guys, because we have no more
    time for structured Q&A. Thank you!
  • 72:36 - 72:41
    postroll music
  • 72:41 - 72:47
    Subtitles created by c3subtitles.de
    in the year 2016. Join and help us!
Title:
Console Hacking
Description:

more » « less
Video Language:
English
Duration:
01:12:48
  • please do not do timing before the transcription is finished. Actually, please do not do timing at all, before we tried to do it automatically! it saves a lot of time!

English subtitles

Revisions