names from flagspaces get truncated
The issue
- Names from the
symbolsflagspace get truncated to 130 characters. - Objective-C recovered names from the
classesflagspace get truncated to 255 characters (I expect similar issues with flags recovered from other types of binaries, C++/Golang for example, and I presume it's because of fixed-size memory allocations).
Reproducing with symbols
Below is a very simple test program to reproduce the issue with symbols, compile this program:
#include <stdio.h>
#include <stdlib.h>
unsigned int LoremipsumdolorsitametconsecteturadipiscingelitNuncmaximusnullalectusinegestasquamsagittisetNullaposuereaccumsaninterdumDonecsapiendiamultriciesquistempusidultricesinpurusSuspendisselaciniaexacmiimperdietvolutpatDonecultricesnullasitamettempuscongueDonecgravidaipsumvitaeconguevenenatissapiennullasol(int x)
{
return (x + 42);
}
int main()
{
printf("(rand() + 42) = %u\n", LoremipsumdolorsitametconsecteturadipiscingelitNuncmaximusnullalectusinegestasquamsagittisetNullaposuereaccumsaninterdumDonecsapiendiamultriciesquistempusidultricesinpurusSuspendisselaciniaexacmiimperdietvolutpatDonecultricesnullasitamettempuscongueDonecgravidaipsumvitaeconguevenenatissapiennullasol(rand()));
}
Load it in radare2, then, fs symbols; f
It should show something like:
0x00001169 22 sym.LoremipsumdolorsitametconsecteturadipiscingelitNuncmaximusnullalectusinegestasquamsagittisetNullaposuereaccumsaninterdumDonecs
130 characters in length
Objective-C
#import <Foundation/Foundation.h>
#include <stdlib.h>
@interface Test : NSObject
- (int) LoremipsumdolorsitametconsecteturadipiscingelitNuncmaximusnullalectusinegestasquamsagittisetNullaposuereaccumsaninterdumDonecsapiendiamultriciesquistempusidultricesinpurusSuspendisselaciniaexacmiimperdietvolutpatDonecultricesnullasitamettempuscongueDonecgravidaipsumvitaeconguevenenatissapiennullasol: (int) x;
@end
@implementation Test
- (int) LoremipsumdolorsitametconsecteturadipiscingelitNuncmaximusnullalectusinegestasquamsagittisetNullaposuereaccumsaninterdumDonecsapiendiamultriciesquistempusidultricesinpurusSuspendisselaciniaexacmiimperdietvolutpatDonecultricesnullasitamettempuscongueDonecgravidaipsumvitaeconguevenenatissapiennullasol: (int) x {
return x + 42;
}
@end
int main()
{
Test* x = [[Test alloc] init];
int y = [x LoremipsumdolorsitametconsecteturadipiscingelitNuncmaximusnullalectusinegestasquamsagittisetNullaposuereaccumsaninterdumDonecsapiendiamultriciesquistempusidultricesinpurusSuspendisselaciniaexacmiimperdietvolutpatDonecultricesnullasitamettempuscongueDonecgravidaipsumvitaeconguevenenatissapiennullasol: rand()];
NSLog(@"rand() + 42 = %@", @(y));
}
Load in radare2, then fs classes; f. It should show output like:
0x100000928 method.Test.LoremipsumdolorsitametconsecteturadipiscingelitNuncmaximusnullalectusinegestasquamsagittisetNullaposuereaccumsaninterdumDonecsapiendiamultriciesquistempusidultricesinpurusSuspendisselaciniaexacmiimperdietvolutpatDonecultricesnullasitamettempus
Which is 255 characters in length.
The names in the JSON output (from fj) are also truncated.
see R_FLAG_NAME_SIZE and https://github.com/radareorg/radare2/pull/24466 right now this is not configurable. would you like to have a config var for that or maybe we can just use 512 instead of 256 like it should be :?
ping? can you try again with master?
do you think this limit should be configurable? Imho the issue has been solved by expanding the current limit. Maybe some tests would make it clear to understand its use. Can we please confirm the issue is solved in your side?
512 would solve the issue for me. I encountered this while reverse-engineering a popular application (and, it's common to have long selector names with lots of arguments). I will test the change this week.
Having the setting configurable could probably help with other apps (I would not expect the reverse engineering framework I use to truncate symbols silently without a warning).
Looking into the change, the macro r_strf_var declares the buffer of size R_FLAG_NAME_SIZE on the stack. If large sizes are expected, maybe it would make sense to allocate it on the heap (or, because the variable is ephemeral, allocate once before the loop, copy method names into it with a large-enough max size, and free it right after the loop). The other advantage is that, in case snprintf copies the maximum value, the code could realloc() the buffer to accomodate the flag it's about to truncate, and still get full-length flags.
The limit was increased, but i'll work on a better solution that doesnt imply a limit later
situation has improved and i would appreciate some feedback, just moving forward but i think we are in a much better situation here