IDA cannot reference symbols within a segment unless that segment has a valid selector, so that's the most important property to set for a new segment. The selector can be set in the 'Create Segment...' dialogue via the field "base in paragraphs".
GetSegmentAttr(here, SEGATTR_SEL)
tells you what the proper selector is, if the cursor is in the segment to be split. You can type the expression right into the input field of the dialogue; by the same token you can type here
into the begin address field and SegEnd(here)
into the end address field.
Here's an IDC snippet (Shift-F2) that splits the current segment at the current position, cloning most relevant properties (including SEGATTR_SEL):
CompileEx(
"class HelperFunctions {"
"copy_seg_attr (src, dst, attr) { SetSegmentAttr(dst, attr, GetSegmentAttr(src, attr)); }"
"};", 0 );
auto ori_seg, ok, fn;
ori_seg = SegStart(here);
ok = AddSegEx(
here,
SegEnd(here),
GetSegmentAttr(here, SEGATTR_SEL),
GetSegmentAttr(here, SEGATTR_BITNESS),
GetSegmentAttr(here, SEGATTR_ALIGN),
GetSegmentAttr(here, SEGATTR_COMB),
ADDSEG_NOSREG );
if (!ok) return Warning("AddSegEx() failed");
fn = HelperFunctions();
fn.copy_seg_attr(ori_seg, here, SEGATTR_PERM);
fn.copy_seg_attr(ori_seg, here, SEGATTR_FLAGS);
fn.copy_seg_attr(ori_seg, here, SEGATTR_ES);
fn.copy_seg_attr(ori_seg, here, SEGATTR_SS);
fn.copy_seg_attr(ori_seg, here, SEGATTR_DS);
fn.copy_seg_attr(ori_seg, here, SEGATTR_TYPE);
fn.copy_seg_attr(ori_seg, here, SEGATTR_COLOR);
RenameSeg(here, AskStr("", "segment name"));
Note: 'inlining' a class definition via Compile() or CompileEx() was the only trick I found for defining a function inside a snippet. It seems to work only in newer IDAs though (tested with 6.6 and 6.7), and only if the Compile() is right at the start of the snippet.
For older IDA versions the helper function has to be defined in some other way, for example in a separate .idc file, and the call to AddSegEx() needs to be replaced with AddSeg().
Also, I couldn't find a way to query the segment class, and so it cannot be copied even though there is a function SetSegClass()
that can set it.
The inverse operation - merging the next segment into the current one - is much simpler:
auto seg_beg, seg_end, next_seg;
seg_beg = SegStart(here);
if (seg_beg == -1) return Warning("no segment here");
next_seg = NextSeg(here);
if (next_seg == SegEnd(here))
{
seg_end = SegEnd(next_seg);
DelSeg(next_seg, SEGMOD_KEEP);
SetSegBounds(seg_beg, seg_beg, seg_end, SEGMOD_KEEP);
Jump(PrevNotTail(seg_end));
}
With a snippet like this you can merge a whole boatload of segments with just a single click per segment, which is handy for memory dumps. Or for undoing accidental segment splits...